Ollama 模型微调¶
为什么要学¶
Ollama 让本地运行大模型变得极其简单,但默认模型未必适合你的场景。通过自定义 Modelfile、量化策略和本地微调,你可以:
- 定制系统提示词和行为风格,打造专属 AI 助手
- 通过量化在消费级硬件上运行更大的模型
- 结合 LoRA/QLoRA 微调让模型学习领域知识
- 控制推理参数(温度、top_p 等)精确匹配业务需求
掌握 Ollama 微调能力意味着你不再受制于通用模型,能以最低成本获得领域专家级别的本地 AI。
核心概念¶
白话解释¶
把 Ollama 想象成一个"模型厨房": - Modelfile 就是菜谱——告诉 Ollama 如何组装一个模型(基础模型 + 系统提示 + 参数) - 量化 是"压缩食材"——用更少的空间存储模型,代价是微小的精度损失 - 微调 是"加入独家调料"——用你的数据训练模型学习特定领域知识
核心概念对照表¶
| 概念 | 说明 | 类比 |
|---|---|---|
| Modelfile | 模型定义文件,指定基础模型、参数、模板 | Dockerfile |
| FROM | 指定基础模型 | Docker的FROM基础镜像 |
| SYSTEM | 设置系统提示词 | 给AI的"角色说明书" |
| PARAMETER | 设置推理参数(temperature等) | 烹饪的火候设置 |
| TEMPLATE | 定义对话格式模板 | 信件的格式模板 |
| ADAPTER | 加载LoRA适配器权重 | 给模型"戴上专业眼镜" |
| 量化(Quantization) | 降低模型精度以减小体积 | 图片压缩(JPEG质量级别) |
| GGUF | llama.cpp使用的模型格式 | 模型的"标准集装箱" |
| Q4_K_M | 4-bit量化方案(质量/大小平衡) | 中等压缩率 |
| Q8_0 | 8-bit量化方案(更高质量) | 低压缩率 |
安装配置¶
前置要求¶
# 确认Ollama已安装
ollama --version
# 如果未安装
curl -fsSL https://ollama.com/install.sh | sh
# macOS
brew install ollama
# 启动Ollama服务
ollama serve
验证环境¶
# 拉取基础模型测试
ollama pull llama3.2:3b
# 测试运行
ollama run llama3.2:3b "Hello, world!"
# 查看已有模型
ollama list
硬件建议¶
| 模型大小 | 最低内存 | 推荐配置 |
|---|---|---|
| 1-3B | 4GB RAM | 任何现代电脑 |
| 7-8B | 8GB RAM | 16GB RAM + GPU |
| 13B | 16GB RAM | 32GB RAM + GPU |
| 70B | 64GB RAM | 多GPU/云服务器 |
快速上手¶
第一个 Modelfile¶
创建一个中文编程助手:
# 文件名: Modelfile.code-assistant
FROM llama3.2:3b
# 设置系统提示词
SYSTEM """你是一位精通Python和JavaScript的高级编程助手。
你的回答简洁、准确,总是提供可运行的代码示例。
使用中文回答问题。"""
# 调整推理参数
PARAMETER temperature 0.3
PARAMETER top_p 0.9
PARAMETER num_ctx 4096
PARAMETER stop "<|eot_id|>"
构建并运行:
# 创建自定义模型
ollama create code-assistant -f Modelfile.code-assistant
# 运行
ollama run code-assistant "用Python写一个快速排序"
# 查看模型信息
ollama show code-assistant
Modelfile 参数详解¶
FROM llama3.2:3b
SYSTEM "你是一位友好的翻译助手"
# 核心参数
PARAMETER temperature 0.7 # 创造性(0-2, 越高越随机)
PARAMETER top_p 0.9 # 核采样阈值
PARAMETER top_k 40 # Top-K采样
PARAMETER num_ctx 8192 # 上下文窗口长度
PARAMETER repeat_penalty 1.1 # 重复惩罚
PARAMETER seed 42 # 随机种子(可复现)
# 停止词
PARAMETER stop "<|end|>"
PARAMETER stop "Human:"
# GPU层数(控制多少层offload到GPU)
PARAMETER num_gpu 35
自定义对话模板¶
FROM llama3.2:3b
TEMPLATE """{{- if .System }}<|start_header_id|>system<|end_header_id|>
{{ .System }}<|eot_id|>{{- end }}
{{- range .Messages }}<|start_header_id|>{{ .Role }}<|end_header_id|>
{{ .Content }}<|eot_id|>
{{- end }}<|start_header_id|>assistant<|end_header_id|>
"""
SYSTEM "你是一位数据科学专家"
PARAMETER temperature 0.4
进阶用法¶
1. 模型量化¶
从 HuggingFace 导入并量化¶
# 安装llama.cpp(用于量化)
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp && make -j
# 下载HuggingFace模型
pip install huggingface-hub
huggingface-cli download TheBloke/Llama-2-7B-Chat-GGUF \
llama-2-7b-chat.Q4_K_M.gguf --local-dir ./models
# 或者从原始权重转换
python convert_hf_to_gguf.py /path/to/model --outtype f16 --outfile model-f16.gguf
# 量化为不同精度
./llama-quantize model-f16.gguf model-Q4_K_M.gguf Q4_K_M
./llama-quantize model-f16.gguf model-Q8_0.gguf Q8_0
量化方案对比¶
| 量化类型 | 体积(7B模型) | 质量损失 | 速度 | 适用场景 |
|---|---|---|---|---|
| Q2_K | ~2.7GB | 明显 | 最快 | 极端资源受限 |
| Q4_0 | ~3.8GB | 较小 | 快 | 移动/边缘设备 |
| Q4_K_M | ~4.1GB | 很小 | 快 | 通用推荐 |
| Q5_K_M | ~4.8GB | 极小 | 中 | 质量优先 |
| Q8_0 | ~7.2GB | 几乎无 | 慢 | 质量敏感任务 |
| F16 | ~14GB | 无 | 最慢 | 基线对比 |
在 Ollama 中使用量化模型¶
# Modelfile.custom-quant
FROM ./model-Q4_K_M.gguf
SYSTEM "你是一位专业助手"
PARAMETER temperature 0.5
PARAMETER num_ctx 4096
2. 使用 LoRA 适配器¶
当你用外部工具微调后得到 LoRA 权重:
# Modelfile.with-lora
FROM llama3.2:3b
# 加载LoRA适配器
ADAPTER ./my-lora-adapter.gguf
SYSTEM "你是医疗领域专家助手"
PARAMETER temperature 0.2
3. 完整微调流程¶
步骤一:准备训练数据¶
// train_data.jsonl
{"messages":[{"role":"system","content":"你是医疗问答助手"},{"role":"user","content":"什么是高血压?"},{"role":"assistant","content":"高血压是指动脉血压持续升高的慢性疾病..."}]}
{"messages":[{"role":"system","content":"你是医疗问答助手"},{"role":"user","content":"糖尿病的症状有哪些?"},{"role":"assistant","content":"糖尿病的典型症状包括多饮、多食、多尿和体重减轻..."}]}
步骤二:使用 Unsloth 进行 QLoRA 微调¶
from unsloth import FastLanguageModel
import torch
# 加载基础模型
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/llama-3.2-3b-Instruct",
max_seq_length=2048,
load_in_4bit=True,
)
# 配置LoRA
model = FastLanguageModel.get_peft_model(
model,
r=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
lora_alpha=16,
lora_dropout=0,
bias="none",
)
# 准备数据集和训练
from trl import SFTTrainer
from transformers import TrainingArguments
trainer = SFTTrainer(
model=model,
train_dataset=dataset,
args=TrainingArguments(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
warmup_steps=5,
max_steps=60,
learning_rate=2e-4,
output_dir="outputs",
),
)
trainer.train()
# 保存为GGUF格式
model.save_pretrained_gguf("my-finetuned", tokenizer, quantization_method="q4_k_m")
步骤三:导入 Ollama¶
# Modelfile.finetuned
FROM ./my-finetuned-unsloth.Q4_K_M.gguf
TEMPLATE """<|begin_of_text|><|start_header_id|>system<|end_header_id|>
{{ .System }}<|eot_id|><|start_header_id|>user<|end_header_id|>
{{ .Prompt }}<|eot_id|><|start_header_id|>assistant<|end_header_id|>
"""
SYSTEM "你是医疗领域专家助手"
PARAMETER temperature 0.2
PARAMETER num_ctx 2048
4. 多模态模型定制¶
# Modelfile.vision
FROM llava:7b
SYSTEM "你是一位图像分析专家,擅长描述和分析图片内容。请用中文回答。"
PARAMETER temperature 0.3
PARAMETER num_ctx 4096
5. 模型管理与分发¶
# 复制/重命名模型
ollama cp code-assistant my-namespace/code-assistant
# 推送到Ollama Hub
ollama push my-namespace/code-assistant
# 删除模型
ollama rm code-assistant
# 查看模型详细信息
ollama show code-assistant --modelfile
# 列出运行中的模型
ollama ps
常见问题¶
Q1: Modelfile 修改后模型没有更新?¶
# 需要重新创建模型
ollama create code-assistant -f Modelfile.code-assistant --force
# 或者先删除再创建
ollama rm code-assistant
ollama create code-assistant -f Modelfile.code-assistant
Q2: 量化后模型质量下降严重?¶
- 7B以下模型建议至少用 Q4_K_M,避免 Q2_K
- 对话/创意类任务对量化更敏感,代码/逻辑类影响较小
- 用 Q5_K_M 或 Q8_0 做质量与性能的折中
Q3: LoRA 适配器格式不兼容?¶
# 确保LoRA转换为GGUF格式
# 使用llama.cpp的convert工具
python convert_lora_to_gguf.py \
--base model-f16.gguf \
--lora-path ./lora-weights \
--outfile lora-adapter.gguf
Q4: 微调数据量需要多少?¶
| 任务类型 | 最少样本数 | 推荐样本数 |
|---|---|---|
| 风格调整 | 50-100 | 200-500 |
| 领域知识 | 500-1000 | 2000-5000 |
| 特定任务 | 100-300 | 500-2000 |
Q5: 如何评估微调效果?¶
# 简单对比评估
import ollama
questions = ["什么是高血压?", "糖尿病如何治疗?"]
for q in questions:
# 原始模型
base = ollama.chat(model='llama3.2:3b', messages=[{'role':'user','content':q}])
# 微调模型
tuned = ollama.chat(model='medical-assistant', messages=[{'role':'user','content':q}])
print(f"Q: {q}")
print(f"Base: {base['message']['content'][:200]}")
print(f"Tuned: {tuned['message']['content'][:200]}")
print("---")
Q6: VRAM 不够怎么办?¶
参考资源¶
- Ollama 官方文档 - Modelfile 完整参考
- Ollama 模型库 - 可用模型列表
- Unsloth - 2x 快速微调工具
- llama.cpp - 量化和推理引擎
- GGUF 格式规范
- LoRA 论文 - 低秩适配方法原论文
- QLoRA 论文 - 量化+LoRA 微调方法