<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>DPO on 方糖猫Blog</title>
    <link>https://ftmao.com/blog/tags/dpo/</link>
    <description>AI 视频、AI Agent 与工程实践笔记</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    <lastBuildDate>Sun, 09 Nov 2025 16:00:00 +0800</lastBuildDate><atom:link href="https://ftmao.com/blog/tags/dpo/index.xml" rel="self" type="application/rss+xml" /><item>
      <title>生成式AI原理与实战（Part 3）学习笔记：嵌入模型、表示微调与生成模型微调</title>
      <link>https://ftmao.com/blog/posts/llm-interview-notes-part3/</link>
      <pubDate>Sun, 09 Nov 2025 16:00:00 +0800</pubDate>
      <guid>https://ftmao.com/blog/posts/llm-interview-notes-part3/</guid>
      <description>&lt;h1 id=&#34;生成式ai原理与实战part-3学习笔记嵌入模型表示微调与生成模型微调&#34;&gt;生成式AI原理与实战（Part 3）学习笔记：嵌入模型、表示微调与生成模型微调&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;这是《生成式AI原理与实战》学习笔记的第三篇。Part 1 聊了大模型的“底层零件”，Part 2 聊了提示工程、Agent 和 RAG；Part 3 则进入“模型训练与微调”领域：怎么训练一个好的文本嵌入模型、怎么在数据少的情况下微调分类模型、怎么用 LoRA/DPO/PPO 把通用大模型变成业务模型。目标读者仍然是&lt;strong&gt;刚接触 AI 的初中级开发者&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;写在前面为什么开发者要懂微调&#34;&gt;写在前面：为什么开发者要懂微调？&lt;/h2&gt;
&lt;p&gt;调用 API 能解决 80% 的问题，但剩下的 20% 往往需要你接触模型本身：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公司私有文档的检索效果差，要不要自己训练嵌入模型？&lt;/li&gt;
&lt;li&gt;标注数据只有几百条，能微调分类模型吗？&lt;/li&gt;
&lt;li&gt;想让大模型输出符合公司风格的文案，除了写 prompt 还能做什么？&lt;/li&gt;
&lt;li&gt;排行榜第一的模型，为什么到自己业务里表现一般？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这篇文章会用“概念 + 图 + 工程直觉”来回答这些问题。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;一文本嵌入模型让语义变成可计算的向量&#34;&gt;一、文本嵌入模型：让“语义”变成可计算的向量&lt;/h2&gt;
&lt;p&gt;嵌入模型（Embedding Model）的作用，是把文本变成固定长度的向量。语义相近的文本，向量距离就小；语义不同的文本，向量距离就大。它是 RAG、语义搜索、推荐系统的核心组件。&lt;/p&gt;
&lt;h3 id=&#34;11-为什么对比学习需要负样本&#34;&gt;1.1 为什么对比学习需要负样本？&lt;/h3&gt;
&lt;p&gt;训练嵌入模型时，如果只告诉模型“这两句话很相似，向量要靠近”，模型可能偷懒：把所有文本都编码成同一个向量。这样无论输入什么，相似度都很高，模型就失去了区分能力。&lt;/p&gt;
&lt;p&gt;负样本的作用就是告诉模型：&lt;strong&gt;这些不相似的文本，向量必须拉开&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    subgraph 只有正样本
        P1[A] --&amp;gt; C[中心点]
        P2[B] --&amp;gt; C
        P3[C] --&amp;gt; C
    end

    subgraph 加入负样本
        N1[A] -.-&amp;gt;|拉近| P[正样本对]
        N2[B] -.-&amp;gt;|拉近| P
        N3[C] --&amp;gt;|推远| P
    end&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;高质量训练的关键是&lt;strong&gt;难负样本（Hard Negatives）&lt;/strong&gt;：那些看起来很像正确答案、但实际不对的样本。比如问“北京在哪里”，错误答案“上海是中国城市”就是一个难负样本，它会让模型学会更细粒度的区分。&lt;/p&gt;
&lt;h3 id=&#34;12-双编码器-vs-交叉编码器&#34;&gt;1.2 双编码器 vs 交叉编码器&lt;/h3&gt;
&lt;p&gt;工业界的语义搜索通常分两阶段：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    Q[查询] --&amp;gt; B[双编码器 Bi-Encoder]
    D[文档库] --&amp;gt; B
    B --&amp;gt; C[候选 Top-k]
    C --&amp;gt; X[交叉编码器 Cross-Encoder]
    X --&amp;gt; R[精排结果]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;特性&lt;/th&gt;
					&lt;th&gt;双编码器&lt;/th&gt;
					&lt;th&gt;交叉编码器&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;计算方式&lt;/td&gt;
					&lt;td&gt;查询和文档分别编码成向量&lt;/td&gt;
					&lt;td&gt;查询和文档拼接后一起输入模型&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;速度&lt;/td&gt;
					&lt;td&gt;快，文档向量可离线预计算&lt;/td&gt;
					&lt;td&gt;慢，需要实时成对计算&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;精度&lt;/td&gt;
					&lt;td&gt;较低，缺乏细粒度交互&lt;/td&gt;
					&lt;td&gt;高，能捕捉词级关系&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;用途&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;召回阶段&lt;/strong&gt;：从海量文档中快速找候选&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;精排阶段&lt;/strong&gt;：对少量候选做精确排序&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;对初级开发者的建议&lt;/strong&gt;：不要一上来就用交叉编码器处理百万文档，会慢得无法接受。标准做法是“双编码器召回 Top-100 + 交叉编码器精排”。&lt;/p&gt;
&lt;h3 id=&#34;13-训练嵌入模型的损失函数怎么选&#34;&gt;1.3 训练嵌入模型的损失函数怎么选？&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;损失函数&lt;/th&gt;
					&lt;th&gt;优点&lt;/th&gt;
					&lt;th&gt;缺点&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;MNR（多负例排序）&lt;/td&gt;
					&lt;td&gt;适合对比学习，能利用批量内负样本&lt;/td&gt;
					&lt;td&gt;依赖高质量负样本，计算随负例增加&lt;/td&gt;
					&lt;td&gt;大规模检索、对比预训练&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;余弦相似度损失&lt;/td&gt;
					&lt;td&gt;方向敏感，计算轻量，适合归一化嵌入&lt;/td&gt;
					&lt;td&gt;对难负样本区分度不足&lt;/td&gt;
					&lt;td&gt;文本相似度、资源受限场景&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Softmax 损失&lt;/td&gt;
					&lt;td&gt;直接优化分类，输出有概率意义&lt;/td&gt;
					&lt;td&gt;嵌入通用性差，不适合检索&lt;/td&gt;
					&lt;td&gt;意图识别、明确分类任务&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;14-没标注数据怎么办tsdae-无监督预训练&#34;&gt;1.4 没标注数据怎么办？TSDAE 无监督预训练&lt;/h3&gt;
&lt;p&gt;TSDAE（Transformer-based Sequential Denoising Auto-Encoder）的思路是：把输入文本加噪声（如随机删词、替换），再让模型重建原文。模型为了重建，必须学会抓住句子的全局语义。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    I[原始句子] --&amp;gt; N[加噪声]
    N --&amp;gt; E[Encoder 编码]
    E --&amp;gt; D[Decoder 重建]
    D --&amp;gt; O[还原原始句子]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;TSDAE 用特殊词元（如 &lt;code&gt;[CLS]&lt;/code&gt;）作为句子表征，而不是平均池化。原因是：&lt;code&gt;[CLS]&lt;/code&gt; 在训练中被迫压缩全局信息以重建整个句子，信号更强；而平均池化会被无关词稀释。&lt;/p&gt;
&lt;h3 id=&#34;15-怎么评测嵌入模型&#34;&gt;1.5 怎么评测嵌入模型？&lt;/h3&gt;
&lt;p&gt;MTEB（Massive Text Embedding Benchmark）是比 STS-B 更全面的评测基准，包含 8 类任务：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语义文本相似度（STS）&lt;/li&gt;
&lt;li&gt;检索（Retrieval）&lt;/li&gt;
&lt;li&gt;重排序（Reranking）&lt;/li&gt;
&lt;li&gt;分类（Classification）&lt;/li&gt;
&lt;li&gt;聚类（Clustering）&lt;/li&gt;
&lt;li&gt;配对分类（Pair Classification）&lt;/li&gt;
&lt;li&gt;摘要评估（Summarization）&lt;/li&gt;
&lt;li&gt;双语文本挖掘（Bitext Mining）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你做的业务是问答检索，就不要只看 STS 分数，要看 Retrieval 和 Reranking 指标。&lt;/p&gt;
&lt;h3 id=&#34;16-增量学习模型需要与时俱进&#34;&gt;1.6 增量学习：模型需要“与时俱进”&lt;/h3&gt;
&lt;p&gt;世界在变化，新词、新概念不断出现。嵌入模型也需要更新：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    A[收集新数据] --&amp;gt; B{分布是否变化？}
    B --&amp;gt;|是| C[概念漂移检测]
    B --&amp;gt;|否| D[继续监控]
    C --&amp;gt; E{性能是否退化？}
    E --&amp;gt;|是| F[增量微调]
    E --&amp;gt;|否| D
    F --&amp;gt; G[更新模型]
    G --&amp;gt; A&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;检测方法包括：监控 KL 散度、KS 检验、在线评估指标等。更新时可以用小步微调，而不是从头训练。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;二表示模型微调把小数据用出大价值&#34;&gt;二、表示模型微调：把小数据用出大价值&lt;/h2&gt;
&lt;p&gt;很多时候我们只有少量标注数据，却想做一个不错的分类或 NER 模型。这就需要“表示微调”的技巧。&lt;/p&gt;
&lt;h3 id=&#34;21-微调时冻结哪些层&#34;&gt;2.1 微调时冻结哪些层？&lt;/h3&gt;
&lt;p&gt;BERT 这类预训练模型，底层学习通用语法和语义，高层学习任务相关特征。微调时可以根据自己的情况决定：&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    I[输入] --&amp;gt; L1[低层 Transformer&amp;lt;br/&amp;gt;通用语法语义]
    L1 --&amp;gt; L2[高层 Transformer&amp;lt;br/&amp;gt;任务相关语义]
    L2 --&amp;gt; H[分类头]
    H --&amp;gt; O[输出]

    style L1 fill:#e1f5e1
    style L2 fill:#fff2cc
    style H fill:#f8cecc&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;场景&lt;/th&gt;
					&lt;th&gt;策略&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;数据很少&lt;/td&gt;
					&lt;td&gt;冻结底层，只微调高层 + 分类头&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;数据较多&lt;/td&gt;
					&lt;td&gt;全模型微调&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;任务与预训练差异大&lt;/td&gt;
					&lt;td&gt;多微调几层&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;资源有限&lt;/td&gt;
					&lt;td&gt;冻结更多层，节省显存&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;22-setfit几百条数据也能做文本分类&#34;&gt;2.2 SetFit：几百条数据也能做文本分类&lt;/h3&gt;
&lt;p&gt;SetFit 是专门做少样本文本分类的框架。它的核心思想是：&lt;strong&gt;先用对比学习微调 Sentence Transformer，再在它生成的向量上训练一个轻量分类器&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    S[少量标注样本] --&amp;gt; P[构造正负样本对]
    P --&amp;gt; C[对比学习微调 Encoder]
    C --&amp;gt; E[生成文本嵌入]
    E --&amp;gt; CL[训练分类器&amp;lt;br/&amp;gt;SVM / Logistic Regression]
    CL --&amp;gt; M[最终分类模型]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;为什么有效？因为即使是每类只有 5 条样本，两两组合也能生成很多训练对。对比学习让同类样本靠近、不同类样本远离，相当于学到了一个“任务专属的嵌入空间”。&lt;/p&gt;
&lt;h3 id=&#34;23-继续预训练拿到领域知识但别丢了通用能力&#34;&gt;2.3 继续预训练：拿到领域知识，但别丢了通用能力&lt;/h3&gt;
&lt;p&gt;让通用 BERT 适应医疗、法律等垂直领域，常用做法是继续预训练。但直接在全领域数据上训练，可能让模型忘掉通用语言知识，这叫&lt;strong&gt;灾难性遗忘&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;缓解方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;混合训练&lt;/strong&gt;：领域数据 + 通用数据一起训练。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分阶段训练&lt;/strong&gt;：先用通用数据 warm-up，再逐步增加领域数据，最后再用少量通用数据巩固。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adapter / LoRA&lt;/strong&gt;：只训练少量新增参数，保留主干模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;EWC（弹性权重巩固）&lt;/strong&gt;：对重要参数加约束，防止大幅偏离。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知识蒸馏&lt;/strong&gt;：用原始通用模型当教师，保留其预测分布。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;24-垂直领域分类三种方案对比&#34;&gt;2.4 垂直领域分类：三种方案对比&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方案&lt;/th&gt;
					&lt;th&gt;优点&lt;/th&gt;
					&lt;th&gt;缺点&lt;/th&gt;
					&lt;th&gt;适用场景&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;直接微调通用 BERT&lt;/td&gt;
					&lt;td&gt;成本低、稳定&lt;/td&gt;
					&lt;td&gt;领域术语理解弱&lt;/td&gt;
					&lt;td&gt;快速验证、术语不复杂的任务&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;继续预训练 BERT 再微调&lt;/td&gt;
					&lt;td&gt;领域适应性强&lt;/td&gt;
					&lt;td&gt;需要大量无标注领域数据&lt;/td&gt;
					&lt;td&gt;有资源、有数据的团队&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;从头预训练领域模型&lt;/td&gt;
					&lt;td&gt;最强领域定制&lt;/td&gt;
					&lt;td&gt;资源消耗巨大、风险高&lt;/td&gt;
					&lt;td&gt;超大规模语料和算力&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;对大多数团队来说，&lt;strong&gt;方案（b）是性价比最高的&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;25-ner-中的子词标签对齐&#34;&gt;2.5 NER 中的子词标签对齐&lt;/h3&gt;
&lt;p&gt;BERT 用 WordPiece 分词，会把一个词拆成多个子词。例如 &amp;ldquo;playing&amp;rdquo; → &amp;ldquo;play&amp;rdquo; + &amp;ldquo;##ing&amp;rdquo;。但 NER 标签是按词标注的，这就需要对齐：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;只标注第一个子词&lt;/strong&gt;：最简单常用，其余子词不参与损失计算。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标签传播到所有子词&lt;/strong&gt;：每个子词都复制原词标签。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标签传播 + 修复规则&lt;/strong&gt;：第一个子词用原标签，后续子词改成 &lt;code&gt;I-&lt;/code&gt; 或 &lt;code&gt;O&lt;/code&gt;，避免 BIO 格式混乱。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;26-嵌入式设备上的小模型多任务训练&#34;&gt;2.6 嵌入式设备上的小模型多任务训练&lt;/h3&gt;
&lt;p&gt;如果要在手机、IoT 设备上跑模型，需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选轻量模型：MiniLM、TinyBERT、DistilBERT。&lt;/li&gt;
&lt;li&gt;多任务学习：共享一个编码器，接不同任务头。&lt;/li&gt;
&lt;li&gt;模型压缩：量化（INT8）、剪枝、知识蒸馏。&lt;/li&gt;
&lt;li&gt;部署格式：ONNX、TFLite。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    I[输入文本] --&amp;gt; E[Shared Encoder]
    E --&amp;gt; C[分类头]
    E --&amp;gt; N[NER 头]
    E --&amp;gt; V[Embedding 头]
    C --&amp;gt; O1[分类结果]
    N --&amp;gt; O2[实体标签]
    V --&amp;gt; O3[语义向量]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;三生成模型微调让通用模型变成你的模型&#34;&gt;三、生成模型微调：让通用模型变成“你的模型”&lt;/h2&gt;
&lt;h3 id=&#34;31-sft监督微调是最常用的起点&#34;&gt;3.1 SFT：监督微调是最常用的起点&lt;/h3&gt;
&lt;p&gt;SFT（Supervised Fine-Tuning）就是准备好 &lt;code&gt;(prompt, response)&lt;/code&gt; 数据对，继续训练模型。比如你想让模型输出更简洁的微信聊天风格，就准备大量“问题 → 简短回答”的样本。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    D[准备 prompt-response 数据] --&amp;gt; S[SFT 微调]
    S --&amp;gt; E[评估效果]
    E --&amp;gt;|不够好| A[补充/清洗数据]
    A --&amp;gt; D
    E --&amp;gt;|效果好| P[上线部署]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;数据量建议（QA 对）：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模型大小&lt;/th&gt;
					&lt;th&gt;目标&lt;/th&gt;
					&lt;th&gt;推荐数据量&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;1B - 7B&lt;/td&gt;
					&lt;td&gt;记住有限文档知识&lt;/td&gt;
					&lt;td&gt;1k - 20k&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;13B - 30B&lt;/td&gt;
					&lt;td&gt;强记忆 + 通用指令&lt;/td&gt;
					&lt;td&gt;10k - 100k&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;70B+&lt;/td&gt;
					&lt;td&gt;企业问答 + 任务泛化&lt;/td&gt;
					&lt;td&gt;50k - 500k&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&#34;32-lora-与-qlora大模型微调的省钱方案&#34;&gt;3.2 LoRA 与 QLoRA：大模型微调的省钱方案&lt;/h3&gt;
&lt;p&gt;全参数微调 70B 模型需要大量 GPU。LoRA 的核心思想是：&lt;strong&gt;不在原始权重上直接更新，而是在每层旁边加两个小矩阵（低秩分解），只训练这两个小矩阵&lt;/strong&gt;。&lt;/p&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    X[输入] --&amp;gt; W[原始权重 W]
    W --&amp;gt; O[输出]
    X --&amp;gt; A[低秩矩阵 A]
    A --&amp;gt; B[低秩矩阵 B]
    B --&amp;gt; O&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;p&gt;LoRA 的参数量大约是全量微调的 &lt;code&gt;1 / (d / 2r)&lt;/code&gt; 倍。例如 d=12288，r=8，参数量减少约 768 倍。&lt;/p&gt;
&lt;p&gt;QLoRA 在此基础上做了&lt;strong&gt;分块量化&lt;/strong&gt;：把权重矩阵切成小块，每块独立量化，保留各自的 scale 和 zero-point。这样比全局量化更精确，能在消费级 GPU 上微调大模型。&lt;/p&gt;
&lt;h3 id=&#34;33-超参数设置与停止训练&#34;&gt;3.3 超参数设置与停止训练&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;超参数&lt;/th&gt;
					&lt;th&gt;推荐范围&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;学习率&lt;/td&gt;
					&lt;td&gt;1e-5 - 2e-4&lt;/td&gt;
					&lt;td&gt;LoRA 可用稍大学习率&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LoRA rank&lt;/td&gt;
					&lt;td&gt;4 - 64&lt;/td&gt;
					&lt;td&gt;小任务 8/16，复杂任务 32+&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;LoRA alpha&lt;/td&gt;
					&lt;td&gt;rank × 2 - rank × 8&lt;/td&gt;
					&lt;td&gt;控制 LoRA 对主模型的影响强度&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;什么时候停止？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;验证集 loss 连续 N 个 epoch 不下降就停。&lt;/li&gt;
&lt;li&gt;不要只看 loss，还要看具体指标（准确率、F1、BLEU、ROUGE）。&lt;/li&gt;
&lt;li&gt;生成任务最好加人工评估，loss 低不代表回答好。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;34-损失函数应该计算输入部分还是输出部分&#34;&gt;3.4 损失函数应该计算输入部分还是输出部分？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;推荐：只计算输出部分&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;推理时模型只负责生成输出，训练时只对输出优化更符合实际使用场景。&lt;/li&gt;
&lt;li&gt;输入部分是人类写好的 prompt，让模型预测它没有意义，还会引入噪声。&lt;/li&gt;
&lt;li&gt;计算量更小，训练更快。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;35-ppo-与-dpo让模型符合人类偏好&#34;&gt;3.5 PPO 与 DPO：让模型符合人类偏好&lt;/h3&gt;
&lt;p&gt;SFT 让模型“学会回答问题”，但不一定“回答得好”。RLHF（基于人类反馈的强化学习）就是解决这个问题。&lt;/p&gt;
&lt;h4 id=&#34;经典-rlhf-三阶段&#34;&gt;经典 RLHF 三阶段&lt;/h4&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    S[SFT 模型] --&amp;gt; R[训练奖励模型&amp;lt;br/&amp;gt;Reward Model]
    R --&amp;gt; P[PPO 强化学习]
    P --&amp;gt; A[对齐后的模型]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SFT&lt;/strong&gt;：训练模型学会基本对话。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练奖励模型&lt;/strong&gt;：收集人类偏好数据，训练一个打分模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PPO 强化学习&lt;/strong&gt;：用奖励模型指导策略模型优化。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;ppo-里的四个角色&#34;&gt;PPO 里的四个角色&lt;/h4&gt;
&lt;div class=&#34;code-block&#34;&gt;
    &lt;button class=&#34;code-copy&#34; type=&#34;button&#34; hidden aria-label=&#34;Copy code to clipboard&#34;&gt;
      &lt;span class=&#34;code-copy-label&#34; aria-hidden=&#34;true&#34;&gt;Copy&lt;/span&gt;
    &lt;/button&gt;
    &lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart TD
    Prompt --&amp;gt; A[Actor&amp;lt;br/&amp;gt;生成回答]
    A --&amp;gt; C[Critic&amp;lt;br/&amp;gt;评估状态价值]
    A --&amp;gt; R[Reward Model&amp;lt;br/&amp;gt;给回答打分]
    A --&amp;gt; Ref[Reference Model&amp;lt;br/&amp;gt;计算 KL 散度&amp;lt;br/&amp;gt;防止跑偏]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模型&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
					&lt;th&gt;是否训练&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Actor&lt;/td&gt;
					&lt;td&gt;生成回答的主模型&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Critic&lt;/td&gt;
					&lt;td&gt;估计价值，计算优势函数&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Reward Model&lt;/td&gt;
					&lt;td&gt;给回答质量打分&lt;/td&gt;
					&lt;td&gt;否（通常预训练好）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Reference Model&lt;/td&gt;
					&lt;td&gt;计算 KL 散度，防止策略偏离初始模型&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&#34;ppo-vs-dpo&#34;&gt;PPO vs DPO&lt;/h4&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;对比项&lt;/th&gt;
					&lt;th&gt;PPO&lt;/th&gt;
					&lt;th&gt;DPO&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;训练范式&lt;/td&gt;
					&lt;td&gt;强化学习（on-policy）&lt;/td&gt;
					&lt;td&gt;监督学习（off-policy）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;是否需要奖励模型&lt;/td&gt;
					&lt;td&gt;需要&lt;/td&gt;
					&lt;td&gt;不需要&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;实现复杂度&lt;/td&gt;
					&lt;td&gt;高&lt;/td&gt;
					&lt;td&gt;低&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;数据利用率&lt;/td&gt;
					&lt;td&gt;低，只能用当前策略生成的数据&lt;/td&gt;
					&lt;td&gt;高，历史偏好数据都能用&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;稳定性&lt;/td&gt;
					&lt;td&gt;较敏感，容易 reward hacking&lt;/td&gt;
					&lt;td&gt;更稳定&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;数据少的时候优先用 DPO&lt;/strong&gt;，它只需要 &lt;code&gt;(prompt, chosen, rejected)&lt;/code&gt; 三元组；等数据量和工程能力都上来了，再考虑 PPO。&lt;/p&gt;
&lt;h3 id=&#34;36-dpo-的-beta-参数&#34;&gt;3.6 DPO 的 beta 参数&lt;/h3&gt;
&lt;p&gt;beta 控制模型对偏好差异的敏感程度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;beta 小：偏好信号平滑，训练稳定，但可能学不到足够强的偏好。&lt;/li&gt;
&lt;li&gt;beta 适中（0.5-1.0）：常用默认值。&lt;/li&gt;
&lt;li&gt;beta 大：偏好差异被放大，模型对偏好更敏感，但可能过拟合或不稳定。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;37-把用户行为变成-dpo-数据&#34;&gt;3.7 把用户行为变成 DPO 数据&lt;/h3&gt;
&lt;p&gt;如果你运营一个 ChatGPT 类网站，用户行为天然就是偏好信号：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;用户行为&lt;/th&gt;
					&lt;th&gt;含义&lt;/th&gt;
					&lt;th&gt;DPO 用法&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;点赞&lt;/td&gt;
					&lt;td&gt;喜欢这个回答&lt;/td&gt;
					&lt;td&gt;当前回答为 chosen&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;点踩&lt;/td&gt;
					&lt;td&gt;不喜欢&lt;/td&gt;
					&lt;td&gt;当前回答为 rejected&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;重新生成&lt;/td&gt;
					&lt;td&gt;否定当前，偏好新的&lt;/td&gt;
					&lt;td&gt;新回答为 chosen，旧的为 rejected&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;复制/分享&lt;/td&gt;
					&lt;td&gt;非常满意&lt;/td&gt;
					&lt;td&gt;当前回答为 chosen&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;对于小红书这类图文混合平台，停留时长受图片影响大，需要结合点赞、收藏等行为综合判断；知乎这类长文本平台，停留时长、评论互动更能反映内容质量。&lt;/p&gt;
&lt;h3 id=&#34;38-对齐隐私与提示词注入&#34;&gt;3.8 对齐、隐私与提示词注入&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;对齐问题&lt;/strong&gt;：模型目标函数与人类真实意图不一致。解决办法包括 RLHF/DPO、安全微调、拒绝训练、输出审查等。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;隐私保护&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;训练前脱敏、移除 PII。&lt;/li&gt;
&lt;li&gt;训练中使用差分隐私优化。&lt;/li&gt;
&lt;li&gt;训练后扫描模型是否记住了敏感信息。&lt;/li&gt;
&lt;li&gt;部署时加输出拦截和 prompt 注入检测。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;通过微调防御提示词注入&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在训练数据里加入大量注入攻击样本，标注正确拒答。&lt;/li&gt;
&lt;li&gt;对抗式微调：生成各种攻击变体让模型学习。&lt;/li&gt;
&lt;li&gt;强化系统角色一致性，让模型坚持原始身份。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;四从面试题到工程实践&#34;&gt;四、从面试题到工程实践&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;嵌入模型优先用现成的&lt;/strong&gt;。MTEB 上排名靠前的模型（如 BGE、E5、GTE）通常足够好用，不要自己从头训练。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据少时试试 SetFit&lt;/strong&gt;。几百条标注也能做出不错的分类器。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大模型微调先 LoRA/QLoRA&lt;/strong&gt;。全参数微调太贵，LoRA 是性价比之选。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;RLHF 先 DPO 后 PPO&lt;/strong&gt;。DPO 实现简单、数据利用率高，适合起步。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要迷信排行榜&lt;/strong&gt;。榜单分数高不代表业务效果好，要结合实际场景评估。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;评估指标要对齐业务目标&lt;/strong&gt;。分类看 F1，检索看 Recall@K，生成看人工评估，不要只看 loss。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;结语&#34;&gt;结语&lt;/h2&gt;
&lt;p&gt;Part 3 的内容从“怎么训练嵌入模型”讲到“怎么微调分类模型”，再到“怎么对齐生成模型”。对初级开发者来说，重点是理解这些技术的&lt;strong&gt;适用场景和 trade-off&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;嵌入模型：双编码器快但粗，交叉编码器慢但准；负样本决定对比学习效果。&lt;/li&gt;
&lt;li&gt;表示微调：数据少就用 SetFit，数据多就全量微调；领域适配要注意灾难性遗忘。&lt;/li&gt;
&lt;li&gt;生成模型微调：SFT 是起点，LoRA 省钱，DPO/PPO 对齐人类偏好。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;掌握这些，你就能从“会调用模型”进阶到“会根据业务需求选择和调整模型”。&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;参考：《生成式AI原理与实战 —— Part 3》&lt;/p&gt;
&lt;/blockquote&gt;
</description>
    </item>
    
  </channel>
</rss>
