我终于理解了微调到底是什么
我构建了一个自定义 AI 模型的应用。
我给它取了个名字 — CodeBot。我给了它个性。我给了它规则。始终用要点回复。始终包含代码。始终以 "Happy coding!" 结尾。
它确实做到了。问 CodeBot 任何问题,它每次都这样回复。
大约有 20 分钟,我以为我微调了一个模型。
然后我深入挖掘。我意识到我根本没有改变模型。
1、我实际做了什么 vs. 微调真正是什么
这就是让我豁然开朗的时刻。
我的应用做了这样的事:
const modelfile = `FROM llama3.2:latest
SYSTEM You are CodeBot. Always reply in bullet points with a code example. End with: Happy coding!
PARAMETER temperature 0.3`
我在编写指令。给模型规则让它遵循。
真正的微调做的事情完全不同。它使用数千个你希望模型如何行为的示例,在 GPU 上通过训练过程运行,并永久改变模型的权重——即定义模型知道什么以及如何思考的内部数字。
我的应用告诉模型如何行为。真正的微调教会模型——而且知识变成永久性的。
区别巨大。我只有通过构建演示并追问为什么感觉太容易了,才真正理解这一点。
2、什么是微调?
微调是获取预训练模型并在你自己的数据上进一步训练它的过程。
基础模型 — Llama 3.2、GPT-4、Claude — 已经知道很多。它在互联网上数十亿句子上进行过训练。微调则是利用这个基础并使其专业化。
可以这样理解。医学院毕业生了解普通医学。微调就是住院医师培训——两年的专业训练使其成为某一特定领域的专家。
微调之后,知识是永久性的。它被烘焙进模型的权重中。你不需要提醒它任何事情。它就是知道。
微调擅长什么:
- 让模型以非常特定的风格一致地回复
- 教授它领域特定的知识 — 医疗、法律、金融
- 让它可靠地遵循非常精确的输出格式
- 移除或减少你不希望它拥有的知识
微调不是什么:
- 让模型访问私有文档的方式 — 那是 RAG
- 可以在笔记本电脑上几秒钟完成的事情 — 它需要 GPU 和训练时间
- 更改模型的系统提示 — 那是我的应用做的事
3、我构建的应用 — 一个微调演示
我的应用做三件事:
- 向基础模型(Llama 3.2)提问
- 使用 Modelfile 创建自定义模型(CodeBot)
- 向 CodeBot 问同样的问题并比较
问题:"用五岁小孩能听懂的方式解释 Promise。"
基础模型回答 — 自由格式、段落、友好的解释、没有特定结构。
CodeBot 回答 — 严格的要点、包含代码示例、以 "Happy coding!" 结尾。每次都这样。
区别立即可见。这就是整个演示的核心。
4、代码 — 实际发生了什么
整个应用就是两个函数和 10 行逻辑。
函数 1 — ask()
async function ask(model, systemPrompt, userQuestion) {
const messages = [];
if (systemPrompt) messages.push({ role: "system", content: systemPrompt });
messages.push({ role: "user", content: userQuestion });
const res = await fetch(`${BASE_URL}/api/chat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ model, stream: false, messages }),
});
const data = await res.json();
return data.message?.content ?? JSON.stringify(data);
}
向任何 Ollama 模型发送系统提示和问题。返回答案。仅此而已。
函数 2 — createCustomModel()
function createCustomModel(name, baseModel, systemPrompt) {
const modelfile = `FROM ${baseModel}
SYSTEM ${systemPrompt}
PARAMETER temperature 0.3`;
writeFileSync("Modelfile", modelfile);
execSync(`ollama create ${name} -f Modelfile`, { stdio: "inherit" });
console.log(`✓ Custom model "${name}" created`);
}
这会将 Modelfile 写入磁盘,并使用 Ollama CLI 注册一个自定义模型。
Modelfile 中的三行:
FROM— 从哪个基础模型开始SYSTEM— 角色和规则PARAMETER temperature 0.3— 较低的温度意味着更专注、更少随机的回复
需要注意的一点 — Modelfile 不会提交到仓库。应用每次运行时都会重新生成它。这是有意设计的。
主要逻辑 — 三个步骤
const question = "Explain promises like I am 5 years old.";
// Step 1 - Ask the base model
const baseAnswer = await ask(MODEL, "You are a helpful assistant.", question);
// Step 2 - Create CodeBot
await createCustomModel("codebot:latest", MODEL,
"You are CodeBot. Always reply in bullet points with a code example. End with: Happy coding!");
// Step 3 - Ask CodeBot the same question
const customAnswer = await ask("codebot:latest", "", question);
同样的问题。两个完全不同的答案。区别就在于烘焙进 Modelfile 的系统提示。
5、Modelfile 实际上是什么
Modelfile 是 Ollama 打包自定义模型的方式。把它想象成一个配方——它指定使用哪个基础模型、赋予什么角色以及如何调整其行为。
FROM llama3.2:latest ← base model
SYSTEM You are CodeBot... ← persona and rules
PARAMETER temperature 0.3 ← behaviour settings
重要提示: 这不是真正的微调。模型的权重——实际学到的知识——没有改变。你只是在用指令包装基础模型。
移除系统提示后,模型会完全恢复为原始行为。
真正的微调会永久改变权重。即使删除所有提示,知识仍然存在。
6、微调 vs. RAG vs. 系统提示 — 真正的区别
这是我在开始构建之前希望看到的对比:
我的应用是第一列。我给了模型一本规则手册。
RAG — 我们在第 9 天构建的 — 是第二列。文档在查询时被获取。
真正的微调是第三列。它的实际流程是这样的:
7、真正的微调实际上是什么样的
如果你想要真正微调一个模型,这里有五个步骤:
步骤 1 — 收集训练数据 创建问答对,精确展示你希望模型如何回复。
{ "question": "What is our refund policy?",
"answer": "We offer 30-day returns on all products..." }
步骤 2 — 使用工具训练 将你的问答对输入训练工具如 Unsloth 或 Axolotl。它在 GPU 上运行——Google Colab 可以免费使用。该工具根据你的示例调整模型的权重。
步骤 3 — 导出为 GGUF 将训练好的模型转换为 Ollama 能理解的 GGUF 格式。
步骤 4 — 加载到 Ollama
FROM ./my-finetuned.gguf
SYSTEM "You are a customer support agent..."
步骤 5 — 使用它
ollama run my-expert
整个过程根据训练数据大小和 GPU 性能,需要几分钟到几小时。
9、我在构建时遇到的问题
这些是我遇到的实际问题——在你自己尝试之前值得了解:
问题 1 — Cannot read properties of undefined (reading 'content') 传递空字符串作为系统消息使 Ollama 的 API 出现混乱。通过在系统消息为空时完全跳过它来修复——这就是 if (systemPrompt) 检查的由来。
问题 2 — model 'codebot' not found 模型名需要标签。将 "codebot" 改为 "codebot:latest" 即可。
问题 3 — ollama create 静默失败 Ollama 的 /api/create REST 端点在没有明确错误的情况下失败。切换到直接使用 CLI — execSync('ollama create codebot -f Modelfile') — 立即生效。
小问题,但每个都花费了调试时间。在这里分享它们,这样你就不必再经历这些了。
10、改变我对这件事看法的一点
在构建这个应用之前,我模糊地认为微调就是"在你自己数据上训练 AI"。
构建之后,我理解了这是一个光谱:
系统提示 — 告诉模型如何行为。即时。可逆。不需要 GPU。
RAG — 在查询时让模型访问你的文档。模型不会永久学习任何东西。
微调 — 实际改变模型所知道的内容。永久性。需要训练。知识被烘焙进去。
大多数人称之为"微调"的东西实际上就是系统提示。包括我构建的东西。
这不是批评。系统提示很强大,通常正是你所需要的。但了解区别意味着你选择了正确的工具,而不是默认使用最复杂的那个。
我今天学到的东西:
- 微调永久性地改变模型的权重——知识被烘焙进去
- Ollama 用 Modelfile 做的并不是微调——那是系统提示定制
- Modelfile 有三部分:FROM(基础模型)、SYSTEM(角色)、PARAMETER(行为)
- 真正的微调需要训练数据、GPU 以及 Unsloth 或 Axolotl 等工具
- 系统提示 = 规则手册。RAG = 开卷考试。微调 = 真正学进去了
- 大多数人谈论的"微调"实际上只是巧妙的提示
- 跳过空的系统消息可以防止混淆 Ollama 的 API
- 始终使用模型标签 —
codebot:latest而不仅仅是codebot
GitHub 上的完整项目:github.com/PriyankaMali-13/AI/tree/master/finetune-app
运行它。向 CodeBot 提问。亲自看看区别。
原文链接: I Thought I Fine-Tuned an AI. I Didn't. Here's What Actually Happened.
汇智网翻译整理,转载请标明出处