LLaMA-Factoryを活用した言語モデルのカスタマイズから推論環境構築までの実践的手順を解説します。以下の手順で実施します。
環境構築
ネットワーク最適化後、リポジトリをクローンして依存関係をインストールします。
source /etc/network_accelerator
git clone --depth 1 https://github.com/hiyouga/LLaMA-Engine.git
cd LLaMA-Engine
pip install -e ".[torch,eval]"
モデル取得
Hugging Face CLIでモデルをローカルにダウンロードします。
pip install -U hf-hub-client
hf-hub-client download deepseek-ai/DeepSeek-Refined-Qwen-1.5B --local-dir ./model_repository
トレーニングデータ準備
カスタムデータセットをengine_dataディレクトリに配置し、dataset_manifest.yamlにメタ情報を追加します。
custom_dataset:
file_name: specialized_data.json
format: "用户: {input}\n助手: {output}"
system_prompt: "あなたは専門アシスタントです"
ファインチューニング実行
Webインターフェースを起動してトレーニングを開始します。
llm-engine-cli launch
モデル変換処理
トレーニング完了後、LoRAアダプタを統合しGGUF形式に変換します。
git clone https://github.com/ggerganov/llama-processor.git
python llama-processor/convert_hf_to_gguf.py ./model_repository \
--outtype q4_k_m --output ./optimized_model.gguf
量子化レベルの選択基準:
q4_0:基本的な4ビット量子化(バランス型)q5_k_m:高精度を必要とするタスク向けq8_0:ほぼFP16相当の精度を維持f16:量子化なし(高リソース消費)
推論環境構築
Ollamaでデプロイするための設定ファイルを作成します。
FROM ./optimized_model.gguf
SYSTEM """
{{if .System}}{{.System}}{{end}}
"""
PROMPT """
{{if eq .Role "user"}}<|用户|>{{.Content}}<|助手|>
{{else if eq .Role "assistant"}}{{.Content}}</s>{{end}}
"""
PARAMETER num_ctx 4096
PARAMETER stop "</s>"
モデルをビルドして実行します。
ollama create refined-model --file ModelSpec
ollama run refined-model
重要:プロンプトテンプレートの整合性
ファインチューニング時に使用したテンプレートと推論環境で同一の形式を維持する必要があります。テンプレート取得には以下のスクリプトを使用します。
from engine.data.template import TEMPLATE_REGISTRY
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("./model_repository")
template = TEMPLATE_REGISTRY["deepseek_r1"]
template.validate(tokenizer)
with open("deployment_template.jinja", "w") as f:
f.write(tokenizer.chat_template)
このテンプレートをvLLMやOllamaの設定で指定することで、ファインチューニング効果を維持できます。
動作検証
ローカルAPIエンドポイントで応答を確認します。
from openai import OpenAI
api = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
response = api.chat.completions.create(
model="refined-model",
messages=[{"role": "user", "content": "量子コンピュータの原理を説明してください"}]
)
print(response.choices[0].message.content)