ファインチューニングか RAG か
社内ドメイン適応の第一選択は基本的に RAG だが、語彙・記述スタイル・出力フォーマットの一貫性が重要なケース(医療レポート要約、法律相談ドラフト、製造業の FAQ 自動生成)では LoRA ファインチューニングが効く。本稿では DeepSeek V2.5 16B を題材に PEFT で LoRA を学習し、vLLM の `--enable-lora` で本番アダプタ切替する一連の手順を整理する。
データ準備
- 入力ペアは JSONL で `{"messages": [{"role": "system",...},{"role":"user",...},{"role":"assistant",...}]}` 形式
- 1,000-3,000 ペアあれば十分。質の悪い 30,000 ペアより質の高い 1,500 ペアのほうが良い結果になりやすい
- システムプロンプトは固定にし、ユースケース毎にアダプタを分ける
LoRA 学習スクリプト(HuggingFace TRL)
```python from peft import LoraConfig from trl import SFTTrainer, SFTConfig
lora_config = LoraConfig( r=16, lora_alpha=32, target_modules=["q_proj","k_proj","v_proj","o_proj"], lora_dropout=0.05, bias="none", task_type="CAUSAL_LM" )
config = SFTConfig( output_dir="./lora-medical", per_device_train_batch_size=4, gradient_accumulation_steps=8, num_train_epochs=3, learning_rate=1e-4, bf16=True, logging_steps=10, )
trainer = SFTTrainer( model="deepseek-ai/DeepSeek-V2.5-16B", train_dataset=train_ds, peft_config=lora_config, args=config, ) trainer.train() trainer.save_model() ```
社内 R&D では H100 80GB ×2 で 1,500 サンプル × 3 エポック = 約 40 分。
評価設計
- ドメイン固有評価: 医療なら医師 3 名のスコアリング(事実性・読みやすさ・臨床的妥当性)
- 汎用退行検査: JMMLU を学習前後で比較し、ドメイン特化と引き換えに汎用性能を失っていないか確認
- 出力フォーマット遵守率: 望ましいテンプレートに合致した出力の割合
推論時アダプタ切替(vLLM)
```bash vllm serve deepseek-ai/DeepSeek-V2.5-16B \ --enable-lora \ --lora-modules medical=./lora-medical legal=./lora-legal manufacturing=./lora-mfg \ --max-loras 4 --max-lora-rank 32 ```
リクエスト時に `model: medical` のように指定するだけでアダプタが切り替わる。複数顧客のアダプタを同一 GPU で同時提供する SaaS モデルにも応用できる。
運用上のハマりどころ
- ベースモデルのバージョンとアダプタの整合性: アップデート時は再学習も併走
- アダプタ間のリーク防止: ロギング時にどのアダプタで生成したか必ず記録
- ガードレール: ドメイン特化で安全性が下がる傾向があるため、別途 Guard モデル(Llama Guard 3 等)でのポストフィルタ推奨
まとめ
LoRA は「RAG では取れない一貫性」を入れる強力な手段で、DeepSeek の MIT ライセンス + vLLM の本番アダプタ切替と組み合わせれば、SaaS 型の業務 AI を低コストで構築できる。社内 R&D では月額 GPU 費 350 万円 / 同時アダプタ 12 種類の構成で、複数業種向け業務 AI を 1 サーバ群で提供している。