# 大模型技术之LLM
# 第 1 章 LLM概述与发展历程
大语言模型(Large Language Model, LLM)是当前人工智能领域最具变革性的技术成果之一。它不仅重塑了自然语言处理的技术边界,更成为通用人工智能的核心能力底座。对于AI开发者而言,理解LLM的基本原理、演进路径与产业生态,是开展提示工程、模型微调、部署落地等全流程工作的前提。本章将从基础概念出发,沿着GPT系列的技术脉络梳理大模型的范式革命,并结合2026年的产业现状呈现全球LLM体系全景。
# 1.1 LLM核心概述
# 1.1.1 什么是大语言模型
大语言模型是在海量无标注文本数据上,通过自监督学习预训练得到的大型Transformer语言模型。它的底层逻辑是自回归式的下一词预测:给定前文文本,模型通过统计学习语料中的语言规律与知识分布,输出下一个字符(Token)的概率分布,并逐词生成后续内容。
通过对万亿级语料的学习,LLM不仅掌握了语法、语义等基础语言能力,还涌现出知识问答、逻辑推理、代码生成、多轮对话等跨领域的通用能力,成为可适配多种业务场景的AI能力底座。典型代表包括OpenAI的GPT系列、Meta的LLaMA系列、阿里的通义千问(Qwen)系列、字节的豆包系列等。
# 1.1.2 大语言模型的“三大”特征
我们常说的“大模型”,其“大”主要体现在三个维度:
- 参数量大:模型通常拥有数十亿到上万亿个可训练参数。参数是存储语言知识与规律的载体,更大的参数规模意味着更强的信息存储与特征拟合能力。
- 训练数据量大:预训练阶段覆盖多语言、多领域的庞大语料,从网页、书籍、论文到代码,数据规模通常达到数千亿甚至上万亿Token,确保模型接触到足够丰富的语言模式与世界知识。
- 能力强大:依托规模带来的“涌现效应”,模型具备跨任务的泛化能力。无需针对每个任务单独训练模型,仅通过提示词、微调等轻量方式,即可在问答、摘要、翻译、编程、创意写作等数十种场景下达到接近人类的语言表现。
# 1.1.3 开发者视角的LLM能力边界
对于AI开发从业者,需要清晰认知LLM的能力与局限:它擅长自然语言交互、知识整合、代码生成与创意类任务,但也存在幻觉(生成虚假事实)、复杂推理能力有限、长上下文信息衰减等固有特点。后续章节介绍的提示工程、RAG、微调等技术,本质都是在底座模型的基础上扬长避短,适配具体业务需求。
# 1.2 LLM技术演进:GPT系列的范式革命
谈到大语言模型的发展,GPT系列是绕不开的主线。它的每一次迭代,都刷新了行业对语言模型能力的认知,并定义了主流的技术范式。2022年底ChatGPT的爆火,更是将大模型从学术圈推向了大众视野,开启了通用人工智能的产业化序幕。

ChatGPT的成功并非一蹴而就,而是OpenAI在大规模语言建模领域长期迭代的结果。从2018年的GPT-1到2022年的ChatGPT,四代核心模型在架构、规模、训练范式上持续突破,逐步完成了从“任务专用”到“通用能力”、从“符合语言规律”到“符合人类意图”的跨越。
# 1.2.1 GPT-1:预训练+微调范式的奠基
GPT-1(Generative Pre-trained Transformer-1)是OpenAI在2018年6月发布的初代生成式预训练模型,对应论文《Improving Language Understanding by Generative Pre-Training》。它的核心贡献,是系统化验证了“无监督预训练 + 有监督微调”的两阶段范式,为后续所有大模型的训练流程打下了方法论基础。
# 核心架构
GPT-1采用了Transformer Decoder-only(纯解码器)架构——放弃了原始Transformer的编码器-解码器双结构,仅保留解码器部分,天生适配自回归生成任务。整个模型从下到上分为输入层、Transformer Block堆叠层、输出层三部分,结构如下图所示:

- 输入层:将文本Token映射为词向量,同时叠加可学习的位置嵌入,替代传统的正弦位置编码,让模型自适应学习词序信息。
- Transformer Block:每个模块包含两层子结构——掩码多头自注意力(Masked Multi-Head Self-Attention)与前馈网络(Feed Forward Network),子层前后搭配层归一化(LayerNorm)与残差连接,保证深层模型的梯度稳定传播。
- 输出层:预训练阶段输出下一词的概率分布;微调阶段替换为任务专用的分类头,快速适配下游任务。
除此之外,GPT-1还采用了输入嵌入层与输出词表权重共享的设计,在不损失效果的前提下减少参数量,提升训练稳定性。
# 关键参数
GPT-1的整体规模在今天看来很小,但在当时已经验证了架构的可行性:
| 参数项 | 数值 |
|---|---|
| Transformer层数 | 12 |
| 隐藏层维度(Hidden Size) | 768 |
| 注意力头数 | 12 |
| 前馈网络维度(FFN Size) | 3072 |
| 总参数量 | 1.17 亿 |
# 训练与能力
训练分为标准的两阶段:
- 预训练阶段:使用BooksCorpus数据集(约7000本小说,8亿词),以“预测下一个词”为目标进行自监督训练,让模型习得通用的语法、语义与篇章规律。
- 微调阶段:在少量标注数据上,给模型加上任务分类头进行有监督微调。实验显示,微调后的GPT-1在文本蕴含、问答、语义相似度等12项NLP任务上,全面超越了从零训练的专用模型。
总体而言,GPT-1的历史意义远大于其性能表现——它证明了Decoder-only架构+预训练微调范式的通用性,让NLP领域从“一个任务一个模型”的时代,开始走向“一个底座适配所有任务”的时代。
# 1.2.2 GPT-2:零样本能力与规模效应的发现
GPT-2发布于2019年,对应论文《Language Models are Unsupervised Multitask Learners》。它延续了GPT-1的纯解码器架构,但将参数规模放大了10倍。更重要的是,它首次发现了大模型的零样本(Zero-shot)泛化能力——不用微调、不用改模型结构,只靠自然语言描述任务,模型就能完成问答、翻译、摘要等多种工作。
# 架构优化
相比GPT-1,GPT-2的架构改动不大,核心是两点优化:
- 采用Pre-LayerNorm结构:将层归一化放到每个子层的输入侧,而非输出侧,大幅缓解了大模型训练时的梯度不稳定问题,让深层模型更容易收敛。该设计也成为后续大模型的标准配置。
- 扩大模型规模:最大版本参数量达到15.42亿,是GPT-1的十余倍,同时配套了更大规模的训练数据。
Pre-LayerNorm的结构示意如下图:

# 零样本能力验证
GPT-2最惊艳的成果,是证明了大模型可以在零样本条件下完成跨任务迁移。无需任何微调,仅通过“Q: xxx A:”“把英文翻译成法文:xxx”这类自然语言提示,模型就能执行对应任务。
下图分别展示了GPT-2在问答、翻译任务上的零样本输入输出示例:
| 问答任务示例 |
|---|
![]() |
| 翻译任务示例 |
|---|
![]() |
除此之外,GPT-2还明确验证了缩放定律(Scaling Law):模型性能与参数量、数据量、计算量呈近似对数线性关系,只要持续扩大规模,能力就会持续提升。这一结论直接推动了后续GPT-3等超大规模模型的研发。规模与性能的对应关系如下图所示:

# 关键参数
GPT-2最大版本的核心参数如下:
| 参数项 | 数值 |
|---|---|
| Transformer层数 | 48 |
| 隐藏层维度 | 1600 |
| 注意力头数 | 25 |
| 前馈网络维度 | 6400 |
| 总参数量 | 15.42亿 |
训练使用了OpenAI自建的WebText数据集(约40GB、800万篇网页),覆盖新闻、小说、科技、社交等多个领域,保证了语言风格与知识的多样性。
# 1.2.3 GPT-3:上下文学习与超大规模模型的突破
GPT-3发布于2020年5月,对应论文《Language Models are Few-Shot Learners》。它将参数规模推到了1750亿,是GPT-2的百倍以上,并正式提出了上下文学习(In-Context Learning)的概念——模型不仅能零样本完成任务,还能在输入里给出几个示例(Few-shot),快速学习任务模式,效果接近甚至超过微调后的小模型。
# 架构创新
GPT-3整体仍为Decoder-only架构,但针对超长上下文的效率问题,引入了稀疏注意力机制:在部分Transformer Block中使用局部带状稀疏注意力,只对当前位置固定窗口内的Token计算注意力,而非全局所有Token,大幅降低了长序列下的计算与显存开销。稠密注意力与稀疏注意力在各层交替使用,兼顾全局语义捕捉与计算效率。
稀疏注意力的结构示意如下图:

# 上下文学习
GPT-3最核心的贡献,是把“提示词驱动任务”的模式推向了成熟。如下图所示,只需要在输入中给出任务描述+几个示例,模型就能识别任务规律,并对新的查询生成正确结果,全程不需要更新模型参数。

这种能力彻底改变了模型的使用方式:开发者无需收集标注数据、无需微调模型,只靠设计提示词就能快速搭建业务原型,极大降低了AI应用的门槛。
# 关键参数
GPT-3 175B版本的核心参数如下:
| 参数项 | 数值 |
|---|---|
| Transformer层数 | 96 |
| 隐藏层维度 | 12288 |
| 注意力头数 | 96 |
| 前馈网络维度 | 49152 |
| 总参数量 | 1750 亿 |
训练数据总量约570GB、3000亿Token,覆盖网页、百科、书籍、学术论文、代码等多个领域。模型在数千块V100 GPU上分布式训练数周完成,其算力成本在当时达到了千万美元级别。
# 1.2.4 InstructGPT:人类反馈对齐的里程碑
GPT-3虽然生成能力强大,但有一个核心问题:它的训练目标是“模仿互联网文本的下一词分布”,而非“满足用户的真实指令需求”。这导致它的输出常常冗长、答非所问,甚至生成虚假、有害的内容——也就是模型与人类意图“不对齐(Misalignment)”。
为了解决这个问题,OpenAI在2022年初推出了InstructGPT,对应论文《Training language models to follow instructions with human feedback》。它基于GPT-3底座,通过人类反馈强化学习(RLHF)的三阶段范式,让模型学会遵循人类指令,输出更有用、更真实、更安全的结果。它也是ChatGPT的直接技术前身。
# 核心训练流程
InstructGPT没有改动模型架构,核心创新是训练范式的革新,整体分为三个阶段,流程如下图所示:

阶段1:监督微调(Supervised Fine-tuning, SFT) 首先收集高质量的“指令-回答”人工标注数据,覆盖各类用户常见的指令场景。以这些标注数据为训练集,对GPT-3进行有监督微调,让模型初步学会“根据指令输出合理回答”的模式。
SFT阶段的输入输出结构示意如下图:

这一步之后,模型已经能较好地响应指令,但输出质量仍不稳定,且难以统一评判标准。
阶段2:训练奖励模型(Reward Model, RM) 让SFT模型对同一条指令生成多个不同的回答,由人工标注者按照“有用性、真实性、安全性”等标准对回答进行优劣排序。用这些排序数据训练一个奖励模型,让它学会像人类一样给模型回答打分,输出标量奖励值。
奖励模型的作用,是把模糊的人类偏好转化为模型可优化的数值信号,是连接人类与模型的桥梁。
阶段3:强化学习微调(RLHF) 以奖励模型的打分为奖励信号,使用PPO(近端策略优化)算法,对SFT模型进行强化学习训练。模型每生成一个回答,奖励模型就给出分数,模型根据分数调整自身参数,逐步趋向于生成高分、也就是更符合人类偏好的回答。
经过这三步之后,1.3B参数的InstructGPT,在人类偏好评估中已经超过了175B的原始GPT-3——用百分之一的参数量获得了更好的用户体验,充分证明了对齐技术的价值。
# 能力提升
相比原始GPT-3,InstructGPT的提升集中在四个方面:
- 指令理解更精准:不需要复杂的提示词技巧,普通自然语言指令就能得到符合预期的结果。
- 输出更贴合人类偏好:回答更简洁、更相关、更有用,人类标注者的首选率大幅提升。
- 安全性与真实性提升:幻觉内容、有害输出的比例显著下降。
- 通用能力保留:对齐训练没有损伤模型的泛化能力,在各类NLP基准任务上仍保持优秀表现。
# 1.2.5 ChatGPT:对话交互的产品化落地
2022年11月,OpenAI发布ChatGPT,第一次让大众直观感受到了大模型的能力。它基于InstructGPT的技术路线,针对多轮对话场景做了专门优化,成为了大模型产业化的引爆点。
# 训练特点
ChatGPT的架构与InstructGPT同源,同样采用RLHF三阶段训练,核心区别在数据层面:
- 训练数据以多轮对话格式为主:标注人员模拟用户与AI助手的对话,生成高质量的多轮交互样本,让模型学会保持上下文、追问澄清、承认错误、拒绝不当请求等对话能力。
- 原有InstructGPT的单轮指令数据也被转换为对话格式混合训练,保证通用指令能力不退化。
对话训练数据的格式示意如下图:

整体训练流程仍遵循“SFT→奖励模型→PPO强化学习”的三步框架,只是所有数据都适配了对话场景。
# 核心能力
相比前代模型,ChatGPT带来了更接近真人的交互体验:
- 多轮上下文理解:能够记住前文对话内容,进行连贯的多轮问答与任务交互。
- 错误修正与前提质疑:可以主动承认自身错误,识别用户提问中的错误前提并指出。
- 安全对齐能力:对违法、有害、不当的请求能够识别并拒绝,输出更符合公序良俗。
- 任务适配广泛:从知识问答、文案写作到代码调试、逻辑推理,日常绝大多数语言类任务都能直接胜任。
# 1.2.6 GPT系列演进的范式总结
从GPT-1到ChatGPT,四代模型的迭代,最终沉淀出了大语言模型开发的“预训练-监督微调-对齐”三阶段标准范式,至今仍是业界的主流框架:
- 预训练阶段:在超大规模无标注语料上自监督训练,让模型获得通用语言建模能力、海量世界知识与基础泛化能力,是模型的“底座”。
- 监督微调阶段:用高质量的指令-回答/对话数据微调,让模型学会理解人类指令,输出格式规范的响应,是模型从“会说话”到“能做事”的过渡。
- 对齐阶段:通过RLHF、DPO、KTO等偏好优化方法,让模型输出符合人类价值观,更有用、更诚实、更安全,是模型落地应用的安全保障。
这一范式不仅定义了GPT系列的发展路径,也被全球几乎所有大模型项目所借鉴,成为行业通用的开发标准。
# 1.3 全球LLM生态全景
ChatGPT之后,全球大模型进入高速发展期,形成了闭源商用与开源生态并行、多技术路线百花齐放的格局。不同模型在推理能力、多模态、中文优化、成本效率等方向各有侧重,为开发者提供了丰富的选型空间。
# 1.3.1 全球主流LLM体系
截至2026年6月,行业内主流的大模型体系如下表所示,覆盖闭源API与开源底座两大类别:
| 模型体系 | 研发机构 | 开放策略 | 核心特点 |
|---|---|---|---|
| GPT系列 | OpenAI | 闭源API服务 | 综合能力标杆,推理、多模态能力领先,代表模型GPT-5系列 |
| Gemini系列 | Google DeepMind | 核心闭源+部分开源(Gemma) | 多模态与科研能力突出,长上下文、代码能力强劲 |
| Claude系列 | Anthropic | 闭源API服务 | 超长上下文、安全合规性强,适合企业级长文档场景 |
| LLaMA系列 | Meta | 开源权重 | 开源生态最完善,二次开发与微调资源丰富,是绝大多数开源衍生模型的底座 |
| DeepSeek系列 | 深度求索 | 开源权重+API服务 | 代码、数学推理能力突出,性价比高,开发者生态活跃 |
| Qwen(通义千问)系列 | 阿里巴巴 | 开源权重+API服务 | 中文能力优秀,多模态、长文本、端侧模型布局全面 |
| 豆包(Doubao)系列 | 字节跳动 | 闭源API服务 | 中文理解与生成能力强,多模态创作、工具调用能力突出 |
| Kimi系列 | 月之暗面 | 闭源API服务 | 超长上下文处理见长,适合大文档解析场景 |
| GLM系列 | 智谱AI | 核心闭源+部分开源 | 中文优化深入,开源版本生态完善,适配国内落地场景 |
# 1.3.2 权威评测与行业榜单
大模型的能力评估维度复杂,行业内形成了多个权威评测平台,是开发者选型的重要参考:
LMArena 由加州大学伯克利分校团队发起的开放评测平台,采用“盲测投票”的模式:用户在不知道模型身份的情况下,对两个模型的回答打分排序,最终形成排行榜。这种众包式评测更贴近真实用户体验,是最具公信力的大众评测榜单之一。 官方地址:https://lmarena.ai/leaderboard
司南(OpenCompass) 由上海人工智能实验室发起的开源评测体系,是国内最全面的大模型评测平台。它覆盖语言、推理、知识、代码、指令跟随、智能体等多个维度,支持大语言模型、多模态模型、科学智能等多类评测,结果可复现、体系化强,是国内开发者选型的核心参考。
根据司南2026年6月的官方闭源评测集榜单,当前头部大语言模型的综合得分如下:
- GPT-5.4-2026-03-05(OpenAI):67.3分
- DeepSeek-V4-Pro(深度求索):65.1分
- Claude Opus 4.7(Anthropic):64.0分
- Doubao-Seed-2-0-Pro-260215(字节跳动):63.5分
- Kimi-K2.6(月之暗面):63.4分
可以看到,开源模型与闭源头部的差距正在快速缩小,中文场景下国产模型已经具备极强的竞争力。对于开发者而言,根据业务场景、部署方式、成本预算选择合适的模型底座,比盲目追求参数规模更有价值。
# 第 2 章 LLM架构
如果说数据和算力是大语言模型的燃料,那么架构就是模型的骨架——它决定了模型如何组织参数、如何处理文本、如何学习知识,也直接影响着训练效率、推理速度与最终效果。
本章我们会从最基础的Transformer结构讲起,逐层拆解注意力、前馈网络、归一化、位置编码等核心组件的演进逻辑,最后结合DeepSeek V3、Llama 4、Qwen3等主流开源模型的真实架构设计,帮你建立起完整、可落地的LLM架构认知。
# 2.1 LLM基础架构
当前主流的大型语言模型(LLM)几乎都基于Transformer的Decoder-only(仅解码器)架构构建。这一设计最早由GPT系列模型验证并推广,相比Encoder-Decoder结构,它更适配自回归文本生成的场景,训练与推理的工程实现也更统一,因此逐渐成为通用大模型的标准范式。
从宏观结构上看,一个完整的LLM可以分为三层:输入层、Transformer Block堆叠层、输出层。
# 2.1.1 输入层
输入层是文本进入模型的第一道关口,负责把离散的文字转化为模型可计算的向量表示,分为两步完成:
第一步是分词(Tokenization):原始文本会通过分词器(Tokenizer)拆分为一个个Token(可以是字、词或者子词),每个Token对应词表中的一个索引。现代LLM普遍采用BPE(字节对编码)类分词器,词表大小通常在几万到十几万量级,词表规模会直接影响后续Embedding层的参数量。
第二步是向量化:每个Token索引会被映射为对应的词向量(Token Embedding),形成初始的语义表示。同时,为了让模型感知文本的顺序,还需要叠加位置编码(Position Encoding),补充序列的位置信息。
最终,输入层输出同时携带语义与位置信息的向量序列,送入后续的Transformer Block进行逐层计算。
# 2.1.2 Transformer Block
Transformer Block是LLM的核心计算单元,模型的层数(比如7B模型通常32层,70B模型通常80层)决定了模型的深度,也对应着模型的抽象理解能力。每一个Block内部都包含两大核心模块:自注意力机制(Self-Attention)和前馈网络(Feed Forward Network, FFN),并通过残差连接与归一化层包裹,保证深层网络的训练稳定性。
- 自注意力机制:让模型在处理当前Token时,能够动态关注序列中所有历史Token的语义信息,从而捕捉长距离的依赖关系,比如代词指代、上下文逻辑关联等。
- 前馈网络:对每个Token的向量独立做非线性变换,提升模型的特征表达能力,是模型“记忆知识”的主要载体。
几十上百层Transformer Block堆叠在一起,通过逐层的信息提炼与变换,最终让模型具备复杂的语言理解与生成能力。
# 2.1.3 输出层
输出层负责把Transformer Block最终输出的隐藏向量,转化为词表上的概率分布,从而预测下一个Token。
标准实现是通过一个线性投影层,将隐藏维度映射到词表维度,再经过Softmax计算得到每个Token的生成概率。为了减少参数量,绝大多数LLM都会采用权重共享设计:输出层的投影矩阵与输入层的Token Embedding矩阵共用同一套参数,既能降低内存占用,也能提升训练稳定性。
推理时模型采用自回归生成的方式:每次预测出一个Token,把它拼回输入序列的末尾,再继续预测下一个,循环往复直到生成结束符或者达到最大长度。
# 2.2 LLM架构演进
从2017年Transformer诞生至今,LLM的整体框架并未发生颠覆性变化,但内部的各个组件一直在持续迭代优化。演进的核心目标非常明确:在尽可能不损失模型效果的前提下,提升训练稳定性、降低推理成本、支持更长的上下文、适配更大的模型规模。
下面我们从注意力、前馈网络、归一化残差、位置编码四个核心维度,拆解LLM架构的演进路径。
# 2.2.2 注意力机制(Attention)
注意力是Transformer的灵魂,它决定了模型如何利用上下文信息,直接影响模型的理解能力与推理效率。随着模型规模越来越大、生成序列越来越长,传统的多头注意力在工程上的瓶颈越来越突出,也催生了一系列优化方案。
# 2.2.2.1 MHA(Multi-Head Attention,多头注意力)
MHA是Transformer原生的注意力机制,也是所有优化方案的基准。它的核心思想是:把输入向量拆成多个独立的“注意力头”,每个头分别学习不同子空间的注意力模式,最后再把结果拼接起来,从而提升模型的表达能力。
在训练阶段,MHA可以并行计算所有Token的注意力,效率很高;但到了推理阶段,自回归逐Token生成的模式,会让MHA出现明显的性能瓶颈,这就需要先理解一个关键概念:KV Cache。
在自回归生成中,每生成一个新Token,都需要和前面所有历史Token做注意力计算。如果每一步都重新计算所有历史Token的Key和Value,会产生大量重复计算,如下图所示:

为了避免重复计算,推理时会把所有历史Token的Key和Value缓存下来,后续步骤直接复用,这就是KV Cache机制,如下图所示:

KV Cache解决了重复计算的问题,但也带来了新的瓶颈:随着上下文长度增加,缓存的KV数据量会线性增长。而在MHA中,每个注意力头都有独立的Key和Value,头数越多,KV Cache的体积就越大。对于大模型长序列场景,KV Cache会占用大量显存,还会带来极高的内存带宽开销,成为推理速度的主要瓶颈。
# 2.2.2.2 MQA(Multi-Query Attention,多查询注意力)
为了压缩KV Cache的体积,Google在2019年提出了MQA(多查询注意力),核心思路非常直接:所有查询头共享同一套Key和Value,不再每个头单独维护。
结构上的对比如下图所示:

这种设计让KV Cache的体积直接缩小到原来的1/H(H为注意力头数),大幅降低了内存占用和带宽压力,推理速度提升非常显著:

但代价也很明显:所有头共享同一套KV,会削弱注意力的表达多样性,导致模型效果有一定下降,尤其是在复杂推理、长上下文任务上:

同时MQA还存在训练不稳定、微调方差大的问题。整体来看,MQA是一种“极致换效率”的方案,适合对速度要求极高、对精度容忍度较高的场景。
# 2.2.2.3 GQA(Group-Query Attention,分组查询注意力)
既然MHA效果好但效率低,MQA效率高但效果有损失,自然就出现了折中的方案——GQA(分组查询注意力),由Google在2023年正式提出。
GQA的核心逻辑是:把所有查询头分成若干个组,每组内部共享一套Key和Value,组之间相互独立。相当于在MHA和MQA之间取了一个平衡点,结构对比如下图所示:

举个例子,如果总共有32个查询头,分成8组,那么就只需要8套KV,KV Cache体积是MHA的1/4,是MQA的8倍。
从效果与速度的权衡来看,GQA的表现非常出色。原论文在T5-XXL模型上的实验显示:GQA-8的推理速度只比MQA慢一点点,但效果已经非常接近完整的MHA:

| 模型 | 推理时间/样本 | 平均任务性能 |
|---|---|---|
| MHA-XXL | 1.51s | 47.2 |
| GQA-8-XXL | 0.28s | 47.1 |
| MQA-XXL | 0.24s | 46.6 |
可以看到,GQA用极小的速度代价,换回了几乎和MHA持平的效果,性价比非常高。也正因为如此,GQA成为了当前LLM的主流选择,LLaMA 2/3/4、Qwen、Mistral等主流模型都采用了这一结构。
# 2.2.2.4 MLA(Multi-Head Latent Attention,多头潜在注意力)
GQA已经做到了效果与效率的良好平衡,但DeepSeek团队在2024年提出的MLA(多头潜在注意力),走出了另一条更激进的优化路线:不再通过“分组共享KV”来压缩缓存,而是直接把KV压缩到低维的“潜在向量”里。
MLA的核心设计是:先通过一个降维投影,把原本高维的Key和Value共同压缩成一个低维的潜在向量(Latent Vector),推理时只缓存这个低维向量;计算注意力时,再通过升维投影恢复出各个头的KV。整体结构对比如下图所示:

除此之外,MLA还设计了解耦的RoPE方案,解决了低秩压缩与位置编码的兼容性问题。最终的效果非常亮眼:KV Cache体积大幅缩小的同时,模型效果不仅没有下降,甚至还超过了原生MHA。
下表是DeepSeek-V2论文中的消融实验结果,可以直观看到MLA的优势:

以大规模MoE模型为例,MLA的KV Cache仅为MHA的4%左右,同时在BBH、MMLU、C-Eval等多个基准上效果都优于MHA。在DeepSeek-V2上,MLA配合其他优化,让整体KV缓存减少了93.3%,生成吞吐量提升了5.76倍,实现了效果与效率的双重提升。
目前MLA主要应用在DeepSeek系列模型中,是高效注意力架构的重要探索方向。
# 2.2.3 前馈网络(Feed Forward Network)
如果说注意力负责“理解上下文关系”,那么前馈网络(FFN)就负责“处理和记忆知识”。它是Transformer Block中参数量占比最高的模块,通常占总参数的2/3左右,其结构与激活函数的设计,直接影响模型的表达能力与训练稳定性。
FFN的演进主要沿着两个方向:一是激活函数的迭代,二是结构从稠密走向稀疏(MoE)。
# 2.2.3.1 激活函数的演进
激活函数为网络引入非线性,是模型能够学习复杂模式的关键。LLM发展过程中,激活函数经历了从ReLU到GELU、SiLU,再到门控GLU家族的迭代,核心目标是提升训练稳定性与模型效果。
ReLU ReLU是深度学习时代最经典的激活函数,形式非常简单:对输入取max(0, x),负区间直接截断为0。
函数曲线如下图所示:

ReLU的优势是计算简单、正区间梯度恒定,在早期的中小模型中应用广泛。但它的缺陷也很明显:负区间梯度为0,会导致“神经元死亡”(一旦输入为负就永久失活);同时硬截断的非线性不足,深层Transformer训练时容易不稳定。在现代大语言模型中,ReLU已经基本被淘汰。
GELU GELU(高斯误差线性单元)是GPT-2/3、BERT等早期Transformer模型的标配激活函数。它不再做硬性截断,而是通过正态分布累积函数对输入做柔性的加权,让负区间的输出平滑衰减,而不是直接归零。
函数曲线如下图所示:

GELU全域连续可导,梯度更平滑,不会出现神经元死亡问题,训练稳定性比ReLU好很多,因此在中大型Transformer中一度成为主流。
SiLU / Swish SiLU(Sigmoid线性单元)是另一种平滑激活函数,形式为x乘以sigmoid(x),Swish是它的一般化形式(β=1时两者等价)。
函数曲线如下图所示:

SiLU的特性和GELU接近,同样全域平滑、无硬截断,训练表现和GELU不相上下,计算实现更简单。
GLU及其变体 前面的激活函数都是“单路变换”,而GLU(门控线性单元)采用了双分支门控结构:一路做特征变换,一路做门控筛选,两者逐元素相乘,让模型可以动态控制信息流的通断,表达能力显著提升。
传统FFN与门控FFN的结构对比如下:

把门控分支的激活函数换成不同的形式,就衍生出了GEGLU、SwiGLU、ReGLU等多个变体。大量实验表明,门控结构的效果普遍优于单路激活,其中SwiGLU的综合表现最优,是当前LLM的主流选择。
下图是不同FFN结构在多个任务上的性能对比,可以看到SwiGLU等门控结构全面领先于传统的ReLU/GELU方案:

目前LLaMA、Qwen、DeepSeek等几乎所有主流大模型,都采用了SwiGLU作为FFN的激活结构。
# 2.2.3.2 MoE(混合专家模型)
常规的FFN是稠密结构——每个Token都要经过全部参数计算。当模型规模扩大到千亿级别时,训练和推理成本都会变得极高。MoE(Mixture of Experts,混合专家模型)就是为了解决这个问题而生的,它把FFN从“单一大网络”变成了“多个小专家+路由器”的稀疏结构。
核心思想 MoE把单个大FFN拆分成多个独立的小FFN(每个就是一个“专家”),同时增加一个路由器(Router):对于每个输入Token,路由器只选少数最匹配的专家参与计算,其余专家全部跳过。
包含MoE的Transformer Block整体结构如下:

工作流程 MoE的计算过程可以分为五步,如下图所示:

- 路由打分:路由器接收Token的隐藏向量,为所有专家生成匹配得分。
- Top-k选专家:选取得分最高的k个专家(通常k=2~9),其余专家不参与本次计算。
- 权重归一化:对选中专家的得分做Softmax,得到每个专家的贡献权重。
- 专家并行计算:被选中的专家分别对输入做FFN变换,输出各自的结果。
- 加权求和:把各专家的输出按路由权重加权合并,得到该Token的最终结果。
核心优势 MoE是当前大模型规模化的核心技术之一,它的价值体现在三个方面:
- 高容量、低成本:总参数量可以做得很大(提升模型知识容量),但每次前向传播只有少量专家激活,实际计算量远低于同规模稠密模型,实现了“大模型能力,小模型成本”。
- 专家专业化:路由器会自动把不同类型的Token分配给对应的专家,让每个专家专注于特定领域的模式,提升整体泛化能力。
- 天然分布式友好:专家之间相互独立,可以很方便地分布到不同设备上并行计算,支持超大规模模型的训练与部署。
在具体实现上,不同模型的MoE设计也有差异:比如DeepSeek系列引入了共享专家(所有Token都经过的通用专家),减少专家之间的重复学习;部分模型会采用“Dense与MoE层交替”的排布方式,平衡效果与效率。
# 2.2.4 残差连接与归一化
几十上百层的Transformer Block堆叠,如果没有特殊设计,会出现严重的梯度消失问题,根本无法训练。残差连接与归一化就是解决深层网络训练难题的两大核心技术,它们的组合方式与放置位置,也在持续迭代优化。
# 2.2.4.1 RMSNorm:主流的归一化方案
早期Transformer使用LayerNorm做归一化,它会对每个样本的特征做“减均值、除以标准差”的标准化,同时引入可学习的缩放平移参数。
而现在主流LLM普遍使用RMSNorm(均方根归一化),它是LayerNorm的简化版:去掉了均值中心化的步骤,只根据特征的均方根进行缩放。公式如下:
其中 , 是可学习的缩放参数。
实践证明,均值中心化在深层Transformer中对稳定性的贡献非常有限,去掉之后不仅不影响效果,还能减少计算量,同时训练更稳定。目前RMSNorm已经成为几乎所有主流LLM的标准配置。
# 2.2.4.2 归一化的放置位置
归一化层放在残差结构的哪个位置,对训练稳定性影响很大。行业内主要有三种主流的放置方案,如下图所示:

Post Norm(后归一化) 这是原始Transformer论文采用的方案:先做子层(注意力/FFN)计算,和残差相加之后,再对整体做归一化。
这种方式的问题在于:归一化操作会破坏残差连接的恒等梯度通道,导致反向传播时梯度被扰动,层数越深,梯度越容易消失或者爆炸,训练非常不稳定。现在除了极少数模型外,已经很少使用。
Pre Norm(前归一化) 这是当前绝大多数LLM采用的方案:先对输入做归一化,再送入子层计算,最后和残差直接相加。
这种设计完美保留了残差连接的恒等梯度路径,反向传播时始终有一条梯度为1的直通通道,深层网络也能稳定训练。LLaMA、Qwen、Mistral等绝大多数模型都采用这种结构,是工业界的事实标准。
Post Norm in Residual(残差内后归一化) 这是近年出现的一种变体:子层计算完成后先做归一化,再和残差相加。
它同样保留了恒等梯度通道,同时把子层的输出做了标准化,在部分模型上表现出了更好的训练稳定性。比如OLMo 2就采用了类似的设计,配合QK-Norm进一步平滑训练损失曲线。
除此之外,Gemma 3等模型还采用了“前后都加Norm”的设计,在注意力和FFN的前后都放置归一化层,进一步提升数值稳定性。
# 2.2.5 位置编码
自注意力机制本身是“无序”的——只计算Token之间的相似度,不关心它们的先后顺序。但语言是严格的时序序列,顺序错了语义就完全不同,因此必须引入位置编码,给模型补充序列的位置信息。
位置编码的演进,核心是从“固定/可学习的绝对位置”走向“相对位置编码”,重点提升长上下文外推能力与训练稳定性。
# 2.2.5.1 正余弦位置编码
这是原始Transformer采用的方案,通过一组预定义的正弦、余弦函数,为每个位置生成唯一的编码向量,完全不需要训练。
它的核心优势是:理论上可以通过内积体现相对位置关系,并且支持无限长度外推。但在实际应用中,经过Q、K投影矩阵变换后,原本的几何结构会被破坏,相对位置的特性并不能稳定保留,训练效果并不理想,现在只有少量Encoder-Decoder模型还在使用。
# 2.2.5.2 可学习位置编码
GPT-1/2、BERT等早期模型都采用可学习位置编码:为每个位置分配一个独立的可训练向量,和词向量相加后送入网络。
这种方式的好处是灵活、贴合训练数据,效果不错。但缺陷也很明显:超出训练时的最大长度后就没有对应的编码了,几乎没有外推能力;而且参数量随序列长度线性增长,支持长上下文的成本很高。随着长序列成为刚需,这种方案也逐渐被淘汰。
# 2.2.5.3 旋转位置编码(RoPE)
旋转位置编码(Rotary Position Embedding,RoPE)由苏剑林提出,是当前LLM绝对的主流方案。它的核心思路是:不直接把位置向量加进去,而是对Q和K向量做旋转,通过旋转的角度来体现相对位置。
简单来说,RoPE把Q、K向量按维度两两分组,每个二维子向量根据当前位置旋转对应的角度,如下图所示:

这种设计有一个非常棒的数学性质:两个向量旋转后的内积,只和它们的原始向量以及位置差有关,完美实现了“注意力得分体现相对位置”的目标。
RoPE的优势非常突出:
- 天然相对位置:注意力得分天然只和相对位置差相关,符合语言建模的直觉。
- 零额外参数:只有旋转规则,没有可训练参数,不会增加模型体量。
- 优秀的长外推能力:配合YaRN等扩展方法,可以很方便地把模型上下文从4K扩展到几十K甚至上百K。
也正因为这些优势,RoPE已经成为了现代LLM的标配位置编码方案。
# 2.3 主流开源LLM架构赏析
前面讲了各个组件的演进逻辑,本节我们选取几款代表性的开源大模型,看这些技术在真实产品中是如何组合落地的。
# 2.3.1 DeepSeek V3
DeepSeek V3是DeepSeek团队2024年底发布的大规模MoE模型,也是开源模型中的第一梯队选手。它总参数约671B,推理时仅激活37B参数,在效果接近稠密千亿模型的同时,推理成本低很多。
整体架构如下图所示:

核心架构特点:
- 注意力:采用自研的MLA(多头潜在注意力),极致压缩KV Cache,长序列推理效率极高。
- FFN:采用DeepSeekMoE结构,每层包含1个共享专家+256个路由专家,每个Token激活1个共享专家+8个路由专家,共9个专家参与计算。
- 排布方式:前3层使用稠密FFN,后面全部为MoE层,保证底层基础语义的稳定性。
- 其他:RMSNorm + Pre-Norm结构,RoPE位置编码,SwiGLU激活函数,支持128K上下文。
# 2.3.2 Llama 4 Maverick
Llama 4是Meta在2025年发布的新一代模型系列,其中Maverick(独行侠)是主力版本,总参数约400B,激活参数仅17B,主打极致的推理效率。
架构如下图所示:

核心架构特点:
- 注意力:采用GQA(分组查询注意力),共128个查询头,兼顾效果与效率。
- FFN:经典MoE结构,共128个专家,每个Token仅激活2个专家,稀疏度很高。
- 排布方式:稠密层与MoE层交替出现(每2层交替一次),稠密层隐藏维度更大。
- 其他:SwiGLU激活函数,RoPE位置编码,支持高达512K的上下文长度。
# 2.3.3 Qwen3-235B-A22B
Qwen3是阿里通义千问2025年发布的系列模型,覆盖从轻量到大规模的全场景。其中235B-A22B是MoE旗舰版本,总参数235B,激活参数22B,中英文能力均衡。
架构如下图所示:

核心架构特点:
- 注意力:采用GQA方案,兼容主流推理框架,部署友好。
- FFN:共128个路由专家,每个Token激活8个,没有设置共享专家。
- 排布方式:稠密层与MoE层交替排布,共94层Transformer Block。
- 其他:SwiGLU激活,RMSNorm+Pre-Norm,RoPE位置编码,支持128K上下文。
# 2.3.4 GPT-OSS系列
GPT-OSS是OpenAI在2025年开源的模型系列,包含120B和20B两个版本,均采用MoE架构。其中gpt-oss-120b总参数约117B,单Token激活参数仅5.1B,主打轻量高效的部署体验。
架构如下图所示:

该系列是OpenAI首次开源的大尺寸模型,其架构设计偏向工程实用性,在消费级硬件上也能完成轻量化部署。
# 2.3.5 更多架构参考
如果想了解更多模型的架构对比(比如OLMo 2、Gemma 3、Mistral Small 3.1、Kimi K2等),可以参考Sebastian Raschka的深度博文《The Big LLM Architecture Comparison》,里面有非常详细的横向对比与拆解分析。
# 本章小结
回顾LLM的架构演进,我们可以看到清晰的趋势:
- 注意力:从全量MHA走向高效的GQA、MLA,核心是压缩KV Cache,解决长序列推理的带宽瓶颈。
- 前馈网络:从稠密FFN走向稀疏MoE,核心是用更低的计算成本换取更大的模型容量。
- 归一化:从LayerNorm+Post-Norm走向RMSNorm+Pre-Norm,核心是提升深层网络的训练稳定性。
- 位置编码:从绝对位置走向RoPE相对位置,核心是支持更长的上下文与更好的外推能力。
理解这些组件的设计逻辑与取舍,是后续做模型微调、推理优化、二次开发的重要基础。
# 第 3 章 LLM适配方法
# 3.1 为什么需要模型适配
通用大语言模型在开放域聊天、通用问答等场景下已经展现出很强的能力,但当我们把它落地到具体业务时——比如企业客服、法律文书生成、医疗咨询、特定格式的代码输出——往往会出现各种“水土不服”:专业术语不懂、输出格式混乱、知识过时、回答风格不符合要求、频繁出现幻觉。
这并不是模型本身能力不足,而是通用预训练没有针对你的业务场景做定制化。模型适配就是解决这个问题的核心手段:在通用预训练模型的基础上,通过不同技术手段调整模型的输入或行为,使其满足特定场景的功能、效果与稳定性要求。
按照“改动成本从低到高、适配深度从浅到深”排序,工业界最主流的四类适配方案分别是:提示词工程、检索增强生成(RAG)、微调、继续预训练。本章我们逐一拆解每种方法的原理、优劣势与适用场景,最后给出可落地的选型策略。
# 3.2 四类核心适配方法详解
# 3.2.1 提示词工程(Prompt Engineering)
提示词工程是所有适配方案中成本最低、迭代最快、最常用的一种,它的本质是:不修改模型任何参数,仅通过优化输入的提示文本,引导模型输出符合预期的结果。
很多人对提示词工程的理解停留在“写好提示语”,实际上它是一门完整的学科。根据权威指南 Prompt Engineering Guide 的定义,提示词工程涵盖了指令设计、少样本示例构建、推理链引导、安全约束、工具调用扩展等多个方向,既能提升任务效果,也能帮助开发者更好地理解模型的能力边界,是大模型应用开发的基础技能。
核心优势:
- 零训练成本:不需要数据标注、不需要GPU算力、不需要改动模型权重,拿来就能用。
- 迭代效率极高:发现输出不符合预期,调整提示词就能立即验证,几分钟即可完成一轮优化。
- 灵活性极强:同一个模型可以通过不同提示词适配完全不同的任务,切换成本几乎为零。
- 无副作用:不会改变模型本身的能力,不存在“越调越差”的灾难性遗忘风险。
局限性:
- 效果有天花板:无法突破模型本身的能力上限。模型不具备的专业知识、学不会的复杂逻辑,仅靠提示词无法弥补。
- 稳定性有限:对于强格式约束、高一致性要求的场景,纯提示词很难做到100%稳定输出。
- 信息承载量有限:受限于模型上下文窗口长度,无法一次性注入大规模私有知识库。
适用场景:
- 快速验证业务需求、搭建MVP原型;
- 通用类任务,如文案生成、日常问答、简单逻辑推理;
- 对输出格式有轻度要求的场景,如结构化JSON输出、固定模板回复。
进阶的提示词技巧包括少样本学习(Few-shot)、思维链(CoT)、角色设定、自我校验等,系统学习可参考官方指南:https://www.promptingguide.ai (opens new window)
# 3.2.2 微调(Fine-tuning)
当提示词工程触及能力天花板,仍然达不到业务要求时,就可以考虑微调。微调的本质是:使用带标注的任务数据,在预训练模型的基础上继续训练,调整模型参数,让模型固化特定的任务模式、输出风格与行为习惯。
根据训练目标不同,微调主要分为两大范式:
监督微调(Supervised Fine-tuning, SFT) 最主流的微调形式。准备“输入-输出”成对的标注数据,让模型直接学习“遇到这类输入,就按这种格式输出”。比如投喂几千条客服问答对,模型就能学会客服的话术风格与回复逻辑;投喂“需求描述-代码实现”的成对数据,就能提升特定场景的代码生成能力。 SFT主要解决“怎么做”的问题,直接定义模型的输出规范与行为模式。
偏好对齐(Preference Alignment) 在SFT基础上的进一步优化。不需要标注标准答案,只需要标注“哪个回答更好”,通过DPO、RLHF等算法让模型输出更符合人类偏好——比如更有用、更安全、更贴合业务语气。 偏好对齐主要解决“怎么做好”的问题,提升输出的整体质量与用户体验。
核心优势:
- 输出稳定性高:模型学会任务模式后,输出一致性远优于提示词工程,适合工业化生产落地。
- 能力提升显著:可以让模型掌握提示词无法稳定实现的复杂任务,如严格格式生成、领域化表达。
- 推理效率高:微调完成后推理和普通模型一致,不需要额外拼接长提示或检索内容,单token延迟更低。
局限性:
- 依赖高质量标注:数据质量直接决定微调效果,数据标注是主要的人力投入项。
- 存在训练成本:需要GPU算力支持,尤其是大模型全参数微调,算力成本较高。
- 有遗忘风险:如果微调数据领域过于单一,可能导致模型丢失部分通用能力(灾难性遗忘)。
- 迭代周期长:从数据准备到训练验收通常需要数天到数周,灵活度低于提示词方案。
适用场景:
- 对输出稳定性、一致性要求极高的生产级场景;
- 强格式约束、强风格统一的任务,如固定格式报表生成、标准化话术客服;
- 提示词工程无法达到效果的复杂专业任务。
# 3.2.3 检索增强生成(Retrieval Augmented Generation, RAG)
RAG是另一种不修改模型参数的适配方案,核心思路是:给模型外挂一个外部知识库,推理时动态从知识库中检索相关信息,和用户问题一起输入模型,让模型基于检索到的事实内容生成回答。
RAG主要解决大模型的三大痛点:静态知识过时、不掌握私有内部知识、容易产生事实性幻觉。
典型工作流程:
- 知识库构建:将企业文档、产品手册、政策文件等文本做分段、向量化处理,存入向量数据库;
- 检索召回:用户提问时,将问题向量化,从知识库中召回最相关的若干文本片段;
- 增强生成:将用户问题+检索到的参考内容拼接成完整提示,交给大模型基于参考信息生成回答。
核心优势:
- 知识可实时更新:只需更新知识库即可,无需重新训练模型,完美适配知识频繁变动的场景。
- 承载海量私有知识:理论上知识库可无限扩容,不受模型上下文窗口限制。
- 可溯源、低幻觉:回答基于检索到的原文生成,可以标注引用来源,可信度远高于纯生成方案。
- 零训练成本:和提示词工程一样不改模型权重,落地成本远低于微调。
局限性:
- 效果依赖检索准确率:检索漏召回、错召回会直接导致回答出错,检索质量是RAG系统的核心瓶颈。
- 只补知识、不补能力:仅能提升知识类任务效果,对推理、创作、代码生成等能力类任务帮助有限。
- 长上下文有成本:检索内容越多,提示词越长,推理速度越慢,算力成本越高。
适用场景:
- 企业内部知识库问答、产品客服、政策咨询等知识密集型场景;
- 知识更新频率高,无法承担反复训练成本的场景;
- 对回答可信度要求高、需要来源溯源的场景。
# 3.2.4 继续预训练(Continued Pre-training)
继续预训练是四类方案中成本最高、适配最深的一种,本质是:在通用预训练模型的基础上,使用大规模领域无标注文本,继续进行自监督语言建模训练,让模型从底层掌握领域的术语体系、表达习惯与知识逻辑。
如果说微调是“教模型做某一件具体的事”,继续预训练就是“先让模型看懂整个领域,再教它做事”。比如通用模型直接做医疗微调效果不佳,先拿数千万份医疗文献、病历做继续预训练,让模型先理解医疗术语与行业逻辑,后续再做SFT效果会大幅提升。
核心优势:
- 领域适配最彻底:从词法、语义到知识体系全面贴合领域,是最深层的领域适配方案。
- 提升下游任务上限:经过领域继续预训练的模型,后续做微调、RAG的效果都会有基础提升。
局限性:
- 投入成本极高:需要海量高质量领域语料,算力需求大,训练周期长,技术门槛高。
- 数据要求严苛:语料质量差、领域不垂直,反而会破坏模型的通用能力。
- 存在通用能力衰减风险:领域语料过于单一,可能导致模型丢失部分通用语言能力。
适用场景:
- 专业性极强、术语密集的垂直领域,如医疗、法律、金融、工业代码;
- 拥有大规模高质量领域语料、需要长期深耕领域场景的情况;
- 通常作为微调的前置步骤使用,很少单独落地。
# 3.3 适配方法选择策略
实际项目中,不需要上来就做微调或继续预训练。工业界普遍遵循“由浅入深、先轻后重”的原则,优先用低成本方案验证需求,再根据效果逐步升级适配方案。
从参数改动程度、算力投入、适配深度三个维度,四种方案的梯度非常清晰:
| 适配方法 | 是否修改模型参数 | 数据要求 | 算力成本 | 适配深度 | 迭代周期 |
|---|---|---|---|---|---|
| 提示词工程 | 否 | 无需标注 | 极低 | 浅层行为引导 | 小时级 |
| RAG | 否 | 需要知识库文本 | 低 | 补充外部知识 | 天级 |
| 微调 | 部分/全部 | 需要成对标注数据 | 中高 | 固化任务行为 | 周级 |
| 继续预训练 | 全部 | 需要大规模无标注语料 | 极高 | 底层领域适配 | 月级 |
对于大参数模型,尤其是MoE架构的稀疏模型,全参数训练的成本会指数级上升,因此轻量级适配方案的性价比尤为突出。如下图中的轻量级MoE模型所示,单步推理仅激活5.1B参数,无论是提示词工程、RAG还是参数高效微调,都能以很低的成本获得可观的适配效果。
通用决策路径建议:
- 优先做提示词工程:任何场景都先从优化提示词起步,快速验证业务可行性。只要能达到要求,就不用上更重的方案。
- 知识类问题加RAG:如果核心痛点是知识不足、幻觉、知识更新,优先上RAG,不要上来就微调——微调很难注入精准的事实知识,还容易引发遗忘。
- 行为/格式问题做微调:如果提示词已经把规则写得非常明确,模型仍然无法稳定输出,或者输出风格、格式、流程不符合要求,再考虑微调。优先选用LoRA等参数高效微调方案降低成本。
- 领域基础差做继续预训练:仅针对高度垂直的专业领域,如果模型连基本术语都无法理解、微调效果极差,再考虑用领域语料做继续预训练,再承接后续微调。
真实业务中往往是多种方案组合使用,比如“RAG+提示词工程”搭建知识库问答系统,“继续预训练+SFT+偏好对齐”打造领域专用模型,可根据实际需求灵活搭配。
# 第 4 章 LLM微调
声明:本章所提到的微调特指监督微调(Supervised Fine-tuning,SFT),即通过成对的指令-响应数据引导模型学习特定任务模式的训练方法。
# 4.1 概述
在上一章的适配方法中我们提到,提示词工程与RAG属于“不改模型参数”的轻量适配,而微调是“改动模型参数”的深度适配。其中监督微调(SFT)是工业界最主流、落地最成熟的微调范式,核心价值体现在三个方面:
- 强化任务执行能力:让模型稳定掌握特定任务的执行逻辑,显著提升复杂场景下的准确率与可靠性,降低输出的随机性。
- 统一输出行为规范:固化模型的输出格式、语气风格与回复结构,确保生产环境下输出一致、可控、符合业务标准。
- 内化领域知识与逻辑:将行业术语、业务规则与领域知识写入模型参数,提升专业场景下的理解与表达能力,减少幻觉。
需要特别强调:微调不是首选方案。实际项目中应优先通过提示词工程、RAG等轻量方法验证需求,只有当这些方法无法达到效果要求时,再考虑引入微调。
通常满足以下条件时,采用SFT的收益会比较高:
- 基础模型在目标任务上表现波动大,经过充分的提示优化、少样本引导后仍达不到精度要求;
- 业务对输出格式、风格、话术有严格的一致性要求,纯提示词无法保证长期稳定输出;
- 用小模型微调后的专用模型,在效果达标的前提下,推理总成本显著低于调用大尺寸通用模型。
# 4.2 基础模型选择
# 4.2.1 Base Model 与 Instruct Model
当前主流大语言模型普遍遵循“预训练 → 监督微调 → 人类偏好对齐”的三阶段开发范式。仅完成第一阶段预训练的模型称为Base Model(基础模型),经过后两阶段优化的模型称为Instruct Model(指令模型),三者的演进关系如下图所示:

两类模型的能力定位差异非常明显:
- Base Model:具备完整的通用语言能力与世界知识,训练目标只有“预测下一个Token”。它没有学习过对话交互、指令遵循的模式,因此无法稳定理解自然语言指令,直接用来做任务效果很差,通常作为二次训练的基底。
- Instruct Model:在Base Model基础上,通过大量指令数据做了SFT,又经过RLHF/DPO等偏好对齐。它天生具备指令理解、多轮对话、安全对齐的能力,拿来就能直接用,也是绝大多数业务微调的起点。
开源社区通常会同时发布同一模型的两个版本,开发者可根据需求自行选择。
# 4.2.2 选择策略
微调起点的选择,直接决定了数据成本、训练难度与最终效果。通用建议如下:
绝大多数业务场景,优先选择Instruct Model作为微调基底。 原因很直观:它已经具备成熟的指令遵循能力与对话能力,微调只需要在此基础上注入领域知识、调整细节行为,不需要从零教模型“理解指令”。通常只需要数千条高质量标注数据就能达到不错的效果,开发成本低、见效快。
只有高度定制化场景,才考虑从Base Model开始训练,比如:
- 任务形式非常特殊,现有Instruct Model的默认对话模式会干扰任务学习;
- 拥有十万级以上的高质量领域数据,希望做深度的领域化定制,打造完全自研的模型体系。
# 4.2.3 微调注意事项
# 基于Instruct Model微调
使用指令模型做微调,有两个最容易踩的坑,需要特别注意:
严格对齐Chat Template Instruct Model在训练时会使用固定的对话模板(Chat Template,比如ChatML格式),把多轮对话、角色信息拼接成完整的文本序列,如下图所示:

微调时必须使用和原模型完全一致的模板来组织训练数据。如果模板不匹配,模型会无法识别角色边界、指令分隔符,轻则输出格式混乱,重则指令理解能力直接退化。
使用较低的学习率 Instruct Model的参数已经高度收敛,贸然用大学习率训练很容易引发“灾难性遗忘”——学会了新任务,却丢掉了原本的通用能力、安全对齐与指令遵循能力。 增量微调推荐使用较小的学习率(LoRA场景通常为2e-4到5e-5量级),做“增量适配”而不是“覆盖重训”,在保留原有能力的基础上平稳注入新知识。
# 基于Base Model微调
如果选择从Base Model开始训练,需要做好两点预期:
- 对数据质量与数量要求更高。必须准备大量规范的指令-响应对,才能从零建立起稳定的指令执行能力,数据量通常要比Instruct微调高一个数量级。
- SFT之后通常还要做偏好对齐。监督微调只能让模型“会回答”,但不能保证回答的质量、安全性与有用性,后续通常需要补充DPO/RLHF等对齐步骤,才能达到可用水平。
# 4.3 微调数据集
数据是微调的核心,数据的质量上限,决定了微调后模型的效果上限。标注质量差、格式混乱的数据,哪怕数量再多,也练不出好用的模型。
# 4.3.1 数据来源
按照获取渠道,微调数据可分为公共数据集与私有数据集两大类。
# 公共数据源
公共数据集适合快速验证方案、做 baseline 测试,主流获取平台包括:
- Hugging Face Hub:全球最大的AI开源社区,托管了数千个NLP数据集,覆盖问答、摘要、翻译、对话等各类任务,可通过
datasets库一键加载。 - ModelScope:阿里旗下的开源平台,中文数据集资源丰富,适配国内开发者的使用习惯。
# 私有数据源
真正决定业务差异化的是私有数据,也是企业微调的核心数据来源。常见的私有数据包括企业内部文档、历史客服对话、业务工单、行业专业语料等。 私有数据通常不是现成的“指令-答案”格式,需要经过清洗、结构化、人工标注等预处理步骤。除了纯人工标注,也可以采用“大模型生成+人工校验”的人机协同模式提升效率,配合Easy Dataset等开源工具快速构建训练集。
# 4.3.2 数据集格式
监督微调的数据集主要分为两类格式:指令式与对话式,分别对应单轮任务与多轮对话场景。
# 指令式格式
指令式格式用于单轮任务,比如翻译、摘要、分类、知识问答等,最经典的是Alpaca格式,每条样本包含三个字段:
instruction:任务指令,描述模型要做什么;input:可选,任务的输入上下文;output:对应的标准答案。
示例:
{
"instruction": "将以下英文翻译成中文",
"input": "Large language models are transforming AI.",
"output": "大语言模型正在改变人工智能。"
}
2
3
4
5
训练时会通过提示模板将三个字段拼接成统一的输入文本,让模型学习“接到这类指令,就输出对应格式的结果”。
# 对话式格式
对话式格式用于多轮对话场景,比如智能客服、聊天助手,主流有两种实现:
ShareGPT格式
源于社区分享的对话数据,通过conversations列表存储多轮消息,用from字段区分角色:
{
"conversations": [
{"from": "human", "value": "你能解释一下什么是机器学习吗?"},
{"from": "gpt", "value": "机器学习是人工智能的一个分支..."}
]
}
2
3
4
5
6
OpenAI格式
OpenAI官方微调API采用的标准格式,通过role字段区分system、user、assistant三类角色,表达能力更强:
{
"messages": [
{"role": "system", "content": "你是一名专业营养师,回答需基于科学知识,不提供医疗诊断。"},
{"role": "user", "content": "下午容易疲惫,有什么健康零食推荐?"},
{"role": "assistant", "content": "下午疲惫是常见现象,可以选择以下几类零食..."}
]
}
2
3
4
5
6
7
无论哪种原始格式,训练时最终都会通过Chat Template转换为模型熟悉的字符串结构,确保模型能正确解析角色与对话边界。
# 4.4 微调方法分类
根据是否更新模型全部参数,监督微调分为两大类:全参数微调与参数高效微调(PEFT)。
# 4.4.1 全参数微调
全参数微调会更新模型的所有权重,理论上能达到最好的适配效果。但大模型参数量动辄数十亿到上千亿,全参微调对显存、算力、训练时间的要求极高,单卡基本无法承载,必须配合分布式训练技术才能落地。
它适合数据充足、对效果要求极致、算力资源充沛的场景,通常是大厂训练基座级模型的选择,普通业务场景很少使用。
# 4.4.2 参数高效微调(PEFT)
# 概述
参数高效微调的核心思路是:不改动模型主体权重,只训练极少量的参数或新增少量可训练模块,就能达到接近全参微调的效果。它的出现,让普通开发者用单张消费级显卡微调大模型成为可能。
PEFT技术经过多年发展,衍生出了Prompt Tuning、Prefix Tuning、Adapter、LoRA等多条技术路线,如下图所示:

在众多方案中,LoRA凭借效果稳定、实现简单、推理无额外开销的优势,成为了当前绝对的主流;其量化增强版QLoRA进一步降低了硬件门槛,是目前工业界微调的首选方案。其余方法因效果、兼容性或稳定性问题,已逐渐退出主流应用。
# LoRA(低秩适配)
核心原理 LoRA(Low-Rank Adaptation)由微软研究院在2021年提出,它的核心发现是:大模型微调过程中,权重的更新量ΔW其实具有“低秩”特性——有效信息远低于表面维度,不需要完整更新整个矩阵。
基于这个特性,LoRA不直接更新原始权重W₀,而是用两个小矩阵A和B的乘积来模拟更新量:
其中r(秩)远小于原始矩阵的维度d、k,通常取8、16即可。最终权重为:
训练时冻结原始权重W₀,只训练A、B两个低秩矩阵;推理时可以把AB合并回原始权重,完全不增加额外计算延迟。
以4096×4096的权重矩阵为例,全参更新需要约1600万参数;而r=8的LoRA,仅需 4096×8 + 8×4096 = 65536 个参数,仅为原始权重的0.4%,参数量大幅减少。
插入位置 LoRA通常插入在Transformer的线性层中,工业界最常用的是只给注意力层的q_proj、v_proj加LoRA:
- 这两个投影矩阵对任务语义最敏感,仅改动这两处就能接近全参微调的效果;
- 参数量与显存开销最小,性价比最高。 如果需要更强的表达能力,也可以扩展到k_proj、o_proj甚至FFN层,但成本会相应上升。
工程细节 实际实现中通常会补充两个优化:
- 缩放系数α:控制LoRA更新量的幅度,公式为 ,保证不同秩r下的数值稳定性。
- LoRA Dropout:对输入做随机丢弃,缓解小数据集下的过拟合问题。
# QLoRA(量化低秩适配)
核心定位 QLoRA是LoRA的量化增强版,2023年由华盛顿大学与微软联合提出。它通过4bit量化技术大幅压缩基础模型的显存占用,让7B级别模型可以在单张24G消费级显卡上完成微调,且效果几乎和全精度LoRA持平,彻底降低了大模型微调的硬件门槛。
QLoRA的整体流程可以概括为:基础模型4bit量化压缩 → 冻结量化权重 → 训练高精度LoRA适配器,如下图所示:

它的效果来自三个核心技术创新:
NF4(4-bit NormalFloat)量化 传统4bit均匀量化是把[-absmax, absmax]区间等分成16个格点,每个权重映射到最近的格点,流程如下图所示:

但大模型的权重服从正态分布,大部分值集中在0附近,两端数值很少。均匀量化会导致0附近量化误差大、两端格点浪费。 NF4专为正态分布设计:按累积概率把分布分成16个等概率区间,取每个区间的中位数作为量化值。这样0附近格点更密集、两端更稀疏,和权重分布完美匹配,大幅降低了量化误差。
双重量化(Double Quantization) 量化本身需要保存缩放因子(absmax),这些高精度的缩放因子累积起来也会占用不少显存。双重量化就是对缩放因子本身再做一次8bit量化,进一步压缩辅助存储开销。
分页优化器(Paged Optimizers) 微调中优化器状态(Adam的一阶矩、二阶矩)往往比模型本身更占显存。分页优化器借鉴操作系统的虚拟内存思路,把优化器状态分成多个页,只把当前层需要的页载入显存,用完就卸载到CPU内存,大幅降低峰值显存占用。
# 4.5 分布式训练
当模型规模更大、数据量更多,单张显卡既装不下模型,训练速度也满足不了需求时,就需要引入分布式训练,通过多设备协同来突破单卡的算力与显存限制。
# 4.5.1 数据并行
数据并行是最基础、最常用的并行策略,核心思路是:每张卡都保存完整的模型副本,各自处理不同的数据分片,最后同步梯度、统一更新。

标准流程分为三步:
- 每张GPU独立处理本地批次数据,完成前向、反向传播,计算出本地梯度;
- 通过集合通信(AllReduce)对所有卡的梯度做汇总平均,得到全局梯度;
- 每张卡用相同的全局梯度独立更新参数,保持模型副本一致。
数据并行的优势是实现简单、计算效率高;缺点是模型状态在每张卡都有完整副本,存在大量存储冗余,模型太大时单卡装不下就无法使用。它适合模型单卡可容纳、需要提升训练吞吐量的场景。
# 4.5.2 流水线并行
当模型太深、单卡放不下时,可以用流水线并行:把模型按层切成多个分段,每个设备负责其中一段,像流水线一样接力完成计算。

前向传播从第一段设备开始,逐层把激活值传给下一段;反向传播则从最后一段开始,梯度逐级回传。这种按层切分的方式会带来一个天然的问题:流水线气泡——设备在等待上下游数据时处于空闲状态,造成算力浪费,如下图所示:

缓解气泡的主流方法是引入微批次(Micro-batch):把一个大批次拆成很多小的微批次,设备处理完一个微批次就立刻处理下一个,不用等整批完成,让流水线尽量填满,大幅提升设备利用率,如下图所示:

# 4.5.3 张量并行
张量并行是更细粒度的并行:把单层内部的矩阵运算拆分到多张卡上,每张卡只保存部分权重、计算部分结果,最后再聚合。

Transformer中最大的计算量来自矩阵乘法,而矩阵乘法天然可拆分。比如把权重矩阵按列切分,激活数据广播到所有卡,各卡独立计算部分结果,最后通过通信拼接出完整输出,如下图所示:

张量并行的通信开销非常大,通常只在单机多卡、高带宽互联(如NVLink)的场景下使用,和流水线并行配合构成“3D并行”的二维。
# 4.5.4 专家并行
专家并行是专为MoE(混合专家)模型设计的并行策略:把不同的专家FFN分布到不同设备上,每张卡只存储和计算部分专家。

MoE结构天然适合并行:专家之间相互独立、没有依赖,直接拆分即可,通信开销远低于张量并行,是大尺寸MoE模型训练的标配并行方式。
# 4.5.5 ZeRO(零冗余优化器)
# 概述
ZeRO(Zero Redundancy Optimizer)由微软提出,是对传统数据并行的深度增强,也是现在大模型训练最核心的技术之一。 传统数据并行里,每张卡都存着完整的参数、梯度、优化器状态,存储冗余度极高。ZeRO的核心思想是“分片存储、按需加载”:把模型状态切分成多份,每张卡只存自己的分片;计算到对应层时,再通过集体通信临时拉取需要的部分,用完就释放。
这样既保留了数据并行的高计算效率,又彻底消除了存储冗余,让单卡可训练的模型规模大幅提升。
# 三个分片阶段
ZeRO分为三个逐级增强的阶段,对应对三类模型状态的分片,如下图所示:

- ZeRO-1:优化器状态分片 只拆分优化器状态,显存约减少4倍,通信量和普通数据并行一致,性价比最高,是最常用的配置。
- ZeRO-2:优化器状态+梯度分片 梯度也做分片存储,显存约减少8倍,通信量保持不变,适合显存比较紧张的场景。
- ZeRO-3:优化器状态+梯度+模型参数全分片 三类状态全部分片,显存占用和数据并行度成反比,比如64卡并行就能减少64倍显存。但通信量会增加约50%,适合超大规模模型的训练。
开发者可以根据模型大小、硬件资源灵活选择阶段,通常ZeRO-2是兼顾效率与显存的最优平衡点。
# 4.6 训练设备选择
# 4.6.1 主流GPU型号
LLM训练高度依赖NVIDIA GPU,核心看重显存容量、显存带宽与计算性能。常用型号参数如下:
| 型号 | 显存容量 | 显存带宽 | BF16/FP16算力 | 互联带宽 | 定位 |
|---|---|---|---|---|---|
| H100 | 80 GB | 3350 GB/s | 494 TFLOPS | 600 GB/s | 旗舰训练卡,大规模集群首选 |
| H800 | 80 GB | 1680 GB/s | 205 TFLOPS | 300 GB/s | 国内特供版,算力互联受限 |
| A100 | 40/80 GB | 2039 GB/s | 156 TFLOPS | 600 GB/s | 经典训练卡,工业界主流 |
| A800 | 40/80 GB | 2039 GB/s | 156 TFLOPS | 300 GB/s | A100国内特供版 |
| RTX 4090 | 24 GB | 1008 GB/s | 65 TFLOPS | 无 | 消费级旗舰,小模型QLoRA微调首选 |
| RTX 3090 | 24 GB | 936 GB/s | 34.5 TFLOPS | 无 | 高性价比消费级卡,入门微调可用 |
# 4.6.2 微调显存估算
微调的显存占用主要由五部分构成:模型参数、梯度、优化器状态、激活值、运行时临时开销。不同微调策略的显存差异极大,下面分别给出估算逻辑。
# 全参数微调(以Adam优化器、FP16混合精度为例)
- 模型参数:FP16存储,占用 = 参数量 × 2 字节
- 梯度:和参数量同规模,FP16存储,占用 = 参数量 × 2 字节
- 优化器状态:Adam存fp32的参数副本、一阶矩、二阶矩,占用 = 参数量 × 4字节 × 3 = 参数量 × 12 字节
- 激活值:和批次大小、序列长度、层数、隐藏维度正相关,可通过激活重计算(Checkpointing)大幅压缩
整体来看,全参微调的显存大约是模型参数体积的10~16倍,比如7B模型全参微调需要近百GB显存,必须多卡分布式才能运行。
# LoRA微调
- 模型参数:原始权重完整加载,FP16存储,占用和全参一致
- 可训练参数:仅LoRA的A、B矩阵,参数量极少,可忽略
- 梯度与优化器状态:仅对应LoRA参数,体积非常小
- 激活值:和全参微调一致,是主要显存开销之一
LoRA主要节省的是优化器与梯度的显存,7B模型LoRA微调通常需要15~20GB显存,24G显卡可以运行。
# QLoRA微调
- 模型参数:4bit量化存储,占用 = 参数量 × 0.5 字节
- LoRA参数、梯度、优化器:和普通LoRA一致,且分页优化器可将优化器卸载到CPU
- 激活值:和LoRA一致
QLoRA将模型权重压缩到原来的1/4,7B模型仅需6~10GB显存即可运行,12G显卡就能完成微调,是消费级硬件的首选方案。
如果需要更精准的估算,可以使用在线显存计算器辅助选型:https://apxml.com/zh/tools/vram-calculator (opens new window)
# 4.7 主流微调工具
生态完善的工具能大幅降低微调的工程门槛,以下是工业界最常用的几类工具,分别覆盖分布式训练、参数高效微调、全流程训练等场景。
# 4.7.1 分布式训练框架
# DeepSpeed
微软推出的大规模分布式训练库,是ZeRO技术的官方实现。它完整支持数据并行、流水线并行、张量并行、专家并行,以及ZeRO全阶段优化,是训练百亿、千亿级模型的标配工具。DeepSpeed生态成熟,被广泛用于训练BLOOM、GLM、LLaMA等知名大模型。
# Accelerate
HuggingFace推出的分布式训练封装库,提供了统一的API,可以一键切换DDP、FSDP、DeepSpeed等不同后端。它和Transformers、PEFT等HF生态工具天然兼容,几行代码就能把单卡训练改成多卡分布式,是中小规模微调场景的常用选择。
# 4.7.2 参数高效微调工具
# PEFT
HuggingFace官方的参数高效微调框架,标准化实现了LoRA、QLoRA、AdaLoRA等主流PEFT方法,和Transformers库的所有模型无缝适配。它的优势是规范、通用、兼容性好,是做算法研究与标准化微调的基准工具。
# unsloth
专注于极致性能的轻量微调库,针对LoRA/QLoRA做了深度内核优化,在保证效果的前提下,训练速度可比原生PEFT快2~5倍,显存占用更低。它原生适配Llama、Qwen、Mistral等主流开源模型,是单卡/少卡快速微调的首选加速工具。
# 4.7.3 全流程训练工具
# TRL
HuggingFace推出的Transformer强化学习库,不仅支持SFT监督微调,还完整实现了DPO、PPO、KTO等多种对齐算法。它和Transformers、Accelerate、PEFT深度集成,适合做从SFT到偏好对齐的完整训练流程。
# LLaMA Factory
一站式大模型微调框架,主打“零代码微调”,提供WebUI可视化界面与标准化命令行脚本。它支持全参微调、LoRA/QLoRA等几乎所有主流微调方案,内置上百种模型适配,覆盖数据处理、训练监控、模型导出全流程。新手无需写训练代码,配置好参数就能启动微调,是工业界落地非常受欢迎的工具。
# 本章小结
LLM监督微调的完整链路可以概括为:选对基底模型 → 做好高质量数据 → 选配合适的微调方法 → 匹配对应硬件与工具 → 执行训练与调优。
对于绝大多数开发者,入门与落地的最优路径是:选择主流的Instruct模型作为基底,准备数千条高质量标注数据,使用QLoRA/LoRA方案,配合LLaMA Factory或unsloth工具,在消费级或入门专业显卡上即可完成一次完整的微调迭代。
# 第 5 章 微调实战
在前一章中,我们系统讲解了LLM微调的理论体系,涵盖微调方法、分布式技术、硬件选型与工具链。本章将进入实操环节,以Qwen3-8B为示例模型,覆盖从单卡轻量化LoRA微调、多卡全参数分布式微调到零代码一体化微调的三种主流落地方案,所有流程均可直接复现,开发者可根据自身算力与业务需求按需选择。
# 5.1 前置环境准备
# 5.1.1 硬件选型
不同微调方案对硬件的要求差异极大,可根据目标方案选择对应设备:
- LoRA/QLoRA微调:单张消费级显卡即可完成,推荐RTX 3090/4090(24GB显存);无本地硬件可租用云GPU服务器,主流平台包括AutoDL、趣算云、智星云、恒源云等。
- 全参数微调:需多卡专业显卡支撑,推荐4张A800(80GB)起步,4张L20可勉强运行;磁盘建议预留10倍以上模型大小的存储空间(8B模型不低于150GB),用于存放检查点。
# 5.1.2 基础环境搭建
所有实战案例均基于Conda虚拟环境部署,以Python 3.10/3.11为基础版本,不同微调场景按需安装对应依赖。
通用环境初始化命令:
# 初始化conda
conda init && source ~/.bashrc
2
模型下载专用环境:
conda create -n modelscope python=3.11
conda activate modelscope
pip install modelscope filelock -i https://pypi.tuna.tsinghua.edu.cn/simple
2
3
# 5.1.3 预训练模型下载
国内推荐通过ModelScope下载模型,速度更稳定。编写下载脚本model_download.py:
from modelscope.hub.snapshot_download import snapshot_download
# 下载4bit量化版(用于LoRA微调)
model_dir = snapshot_download(
'unsloth/Qwen3-8B-unsloth-bnb-4bit',
cache_dir='/root/autodl-tmp/pretrained'
)
# 下载完整FP16版(用于全参数微调)
# model_dir = snapshot_download(
# 'Qwen/Qwen3-8B',
# cache_dir='/root/autodl-tmp/pretrained'
# )
2
3
4
5
6
7
8
9
10
11
12
13
执行下载:
python model_download.py
# 5.2 单卡LoRA微调实战(Unsloth加速版)
Unsloth是当前最主流的轻量化微调加速库,针对LoRA/QLoRA做了深度内核优化,相比原生实现训练速度提升2~5倍、显存占用降低30%,是单卡微调的首选方案。
# 5.2.1 环境安装
conda create -n sft311 python=3.11
conda activate sft311
pip install unsloth transformers trl datasets -i https://pypi.tuna.tsinghua.edu.cn/simple
2
3
Unsloth会自动安装匹配CUDA版本的PyTorch,无需手动配置。
# 5.2.2 核心参数详解
完整的微调流程分为三步:加载模型、配置LoRA、设置训练参数,核心参数说明如下:
1. 模型加载参数(FastLanguageModel.from_pretrained)
| 参数 | 作用 | 推荐值 | 说明 |
|---|---|---|---|
load_in_4bit | 启用4bit量化加载 | True | 显存≤24GB必选,可降低70%显存占用 |
bnb_4bit_quant_type | 量化算法类型 | "nf4" | 正态分布量化,精度与效率最优平衡 |
max_seq_length | 最大序列长度 | 2048 | 长文本任务可提升至8192,显存占用同步增加 |
dtype | 权重数据类型 | None | 自动根据GPU架构选择BF16/FP16 |
2. LoRA配置参数(FastLanguageModel.get_peft_model)
| 参数 | 作用 | 推荐值 | 说明 |
|---|---|---|---|
r | LoRA秩 | 32 | 控制表达能力:值越大能力越强、参数量越高;简单任务设8,复杂任务设32~64 |
lora_alpha | 缩放因子 | 32 | 通常取r或2*r,控制LoRA更新幅度 |
target_modules | 适配层列表 | ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"] | Qwen3需包含FFN门控层,捕捉更丰富的特征 |
lora_dropout | Dropout率 | 0 | Unsloth优化下可关闭,小数据集可设0.1防过拟合 |
use_gradient_checkpointing | 梯度检查点 | "unsloth" | 用计算换显存,比常规实现省30%显存 |
3. 训练配置参数(SFTConfig)
| 参数 | 作用 | 推荐值 | 说明 |
|---|---|---|---|
per_device_train_batch_size | 单卡批次大小 | 8 | 24GB显存可设8,显存不足则降低 |
gradient_accumulation_steps | 梯度累积步数 | 4 | 模拟更大批次,有效批次=批次大小×累积步数 |
learning_rate | 学习率 | 2e-4 | LoRA微调专用推荐值,过高易导致发散 |
optim | 优化器 | "adamw_8bit" | 8bit优化器,显著降低显存占用 |
num_train_epochs | 训练轮数 | 1 | LoRA微调通常1~2轮即可,多轮易过拟合 |
# 5.2.3 完整训练代码
创建训练脚本train_unsloth_lora.py:
from unsloth import FastLanguageModel
import torch
from datasets import load_dataset
from trl import SFTTrainer, SFTConfig
# ========== 1. 加载量化模型与分词器 ==========
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "/root/autodl-tmp/pretrained/unsloth/Qwen3-8B-unsloth-bnb-4bit",
max_seq_length = 2048,
device_map = "auto",
dtype = None,
load_in_4bit = True,
full_finetuning = False
)
# ========== 2. 配置LoRA适配器 ==========
model = FastLanguageModel.get_peft_model(
model,
r = 32,
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
lora_alpha = 32,
lora_dropout = 0,
bias = "none",
use_gradient_checkpointing = "unsloth",
random_state = 3407
)
# ========== 3. 数据集加载与格式化 ==========
def convert_to_qwen_format(examples):
"""将原始数据转换为Qwen标准对话结构"""
conversations = []
for conv_list in examples["conversation"]:
for conv in conv_list:
conversations.append([
{"role": "user", "content": conv['human'].strip()},
{"role": "assistant", "content": conv['assistant'].strip()}
])
return {"conversations": conversations}
def format_func(examples):
"""应用模型官方Chat Template"""
formatted_texts = []
for conv in examples["conversations"]:
formatted = tokenizer.apply_chat_template(
conv,
tokenize=False,
add_generation_prompt=False
)
formatted_texts.append(formatted)
return {"text": formatted_texts}
# 加载JSONL格式数据集
dataset = load_dataset("json", data_files="data/keywords_data_train.jsonl", split="train")
# 转换为标准对话格式
dataset = dataset.map(convert_to_qwen_format, batched=True, remove_columns=dataset.column_names)
# 应用Chat Template
formatted_dataset = dataset.map(format_func, batched=True, remove_columns=["conversations"])
# ========== 4. 初始化训练器并启动 ==========
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = formatted_dataset,
args = SFTConfig(
dataset_text_field = "text",
per_device_train_batch_size = 8,
gradient_accumulation_steps = 4,
warmup_steps = 5,
num_train_epochs = 1,
learning_rate = 2e-4,
logging_steps = 1,
optim = "adamw_8bit",
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
output_dir = "./outputs",
report_to = "none"
),
)
# 打印初始显存状态
gpu_stats = torch.cuda.get_device_properties(0)
start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024**3, 3)
max_memory = round(gpu_stats.total_memory / 1024**3, 3)
print(f"GPU: {gpu_stats.name}, 总显存: {max_memory} GB, 初始占用: {start_gpu_memory} GB")
# 开始训练
trainer_stats = trainer.train()
# 打印训练结果
used_memory = round(torch.cuda.max_memory_reserved() / 1024**3, 3)
print(f"训练耗时: {round(trainer_stats.metrics['train_runtime']/60, 2)} 分钟")
print(f"峰值显存占用: {used_memory} GB, 占比: {round(used_memory/max_memory*100, 2)}%")
# ========== 5. 保存模型 ==========
# 仅保存LoRA适配器(体积小,需搭配基础模型使用)
model.save_pretrained("/root/autodl-tmp/outputs/Qwen3-8B-sft-lora")
tokenizer.save_pretrained("/root/autodl-tmp/outputs/Qwen3-8B-sft-lora")
# 合并权重后完整保存(生产部署推荐)
# model.save_pretrained_merged("./outputs/Qwen3-8B-merged-fp16", tokenizer, save_method="merged_16bit")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
执行训练:
python train_unsloth_lora.py
# 5.2.4 推理验证
训练完成后,编写推理脚本验证效果,支持一次性输出与流式输出两种模式:
import torch
from unsloth import FastLanguageModel
from transformers import TextStreamer
# 加载基础模型+LoRA适配器
base_model_path = "/root/autodl-tmp/pretrained/unsloth/Qwen3-8B-unsloth-bnb-4bit"
lora_path = "/root/autodl-tmp/outputs/Qwen3-8B-sft-lora"
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=base_model_path,
max_seq_length=2048,
load_in_4bit=True,
device_map="auto"
)
model.load_adapter(lora_path)
FastLanguageModel.for_inference(model) # 启用推理加速
model.eval()
# 构造输入
messages = [
{"role": "user", "content": "请提取这段文本的核心关键词:梯度功能材料是基于全新设计概念的新型功能材料..."}
]
input_text = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
inputs = tokenizer(input_text, return_tensors="pt").to(model.device)
# 方式1:一次性输出
outputs = model.generate(**inputs, max_new_tokens=1024, temperature=0.3)
response = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
print("模型回答:", response)
# 方式2:流式输出
# streamer = TextStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
# outputs = model.generate(**inputs, max_new_tokens=1024, streamer=streamer)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 5.2.5 批量评估生成
如需批量生成测试集结果用于效果评估,可使用以下脚本批量推理并保存结果:
import json
from unsloth import FastLanguageModel
# 加载模型(同上,省略重复代码)
# ...
with open('data/test.jsonl', 'r', encoding='utf-8') as fr, \
open('data/test_result.jsonl', 'w', encoding='utf-8') as fw:
for line in fr:
item = json.loads(line.strip())
user_input = item['conversation'][0]['human']
target = item['conversation'][0]['assistant']
messages = [{"role": "user", "content": user_input.strip()}]
input_text = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
inputs = tokenizer(input_text, return_tensors='pt').to(model.device)
outputs = model.generate(**inputs, max_new_tokens=1024)
predict = tokenizer.decode(outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
fw.write(json.dumps({
"input": user_input,
"predict": predict,
"target": target
}, ensure_ascii=False) + '\n')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 5.3 单卡LoRA微调实战(原生Transformers版)
如果不需要Unsloth的加速特性,希望使用标准HuggingFace技术栈,可采用Transformers + PEFT + TRL的原生实现,兼容性更好,适合学习底层原理。
# 5.3.1 环境依赖
pip install transformers peft trl datasets bitsandbytes -i https://pypi.tuna.tsinghua.edu.cn/simple
# 5.3.2 训练代码
import torch
from datasets import load_dataset
from peft import LoraConfig
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from trl import SFTTrainer, SFTConfig
# ========== 1. 加载4bit量化模型 ==========
LOCAL_MODEL_PATH = "/root/autodl-tmp/pretrained/unsloth/Qwen3-8B-unsloth-bnb-4bit"
# 量化配置
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True # 双重量化,进一步省显存
)
model = AutoModelForCausalLM.from_pretrained(
LOCAL_MODEL_PATH,
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained(LOCAL_MODEL_PATH, trust_remote_code=True)
# ========== 2. LoRA配置 ==========
peft_config = LoraConfig(
r=32,
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# ========== 3. 数据集处理(与Unsloth版一致,省略重复代码) ==========
# dataset = ...
# formatted_dataset = ...
# ========== 4. 训练 ==========
trainer = SFTTrainer(
model = model,
processing_class = tokenizer,
peft_config = peft_config,
train_dataset = formatted_dataset,
args = SFTConfig(
dataset_text_field = "text",
per_device_train_batch_size = 1,
gradient_accumulation_steps = 8,
warmup_steps = 5,
num_train_epochs = 1,
learning_rate = 2e-4,
logging_steps = 1,
optim = "adamw_8bit",
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
output_dir = "./outputs",
report_to = "none"
),
)
trainer.train()
# 保存LoRA适配器
trainer.model.save_pretrained("./outputs/Qwen3-8B-peft-lora")
tokenizer.save_pretrained("./outputs/Qwen3-8B-peft-lora")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 5.3.3 推理代码
原生PEFT推理需手动合并权重:
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
from peft import PeftModel
base_model_path = "/root/autodl-tmp/pretrained/unsloth/Qwen3-8B-unsloth-bnb-4bit"
lora_path = "./outputs/Qwen3-8B-peft-lora"
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16
)
base_model = AutoModelForCausalLM.from_pretrained(
base_model_path, quantization_config=bnb_config, device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(lora_path)
# 加载并合并LoRA权重
model = PeftModel.from_pretrained(base_model, lora_path)
model = model.merge_and_unload() # 合并到基础模型
model.eval()
# 后续生成逻辑与Unsloth版一致
# ...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 5.4 多卡全参数微调实战(DeepSpeed)
当LoRA效果无法满足业务要求、需要深度定制模型能力时,可采用全参数微调。全参微调显存开销大,必须借助分布式训练技术,这里以最主流的DeepSpeed + ZeRO Stage3为例讲解。
# 5.4.1 环境准备
conda create -n sft_all python=3.11
conda activate sft_all
# 安装匹配CUDA版本的PyTorch
pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu124
# 安装依赖
pip install transformers trl datasets deepspeed -i https://pypi.tuna.tsinghua.edu.cn/simple
# 优化显存碎片
export PYTORCH_CUDA_ALLOC_CONF="expandable_segments:True"
2
3
4
5
6
7
8
# 5.4.2 DeepSpeed配置文件
创建ds_config/deepspeed_stage3_config.json,使用ZeRO Stage3 + CPU卸载,最大化节省显存:
{
"zero_optimization": {
"stage": 3,
"offload_optimizer": {"device": "cpu", "pin_memory": true},
"offload_param": {"device": "cpu", "pin_memory": true},
"overlap_comm": true,
"contiguous_gradients": true,
"stage3_gather_16bit_weights_on_model_save": true
},
"optimizer": {
"type": "Adam",
"params": {"lr": "auto", "betas": "auto", "weight_decay": "auto"}
},
"fp16": {
"enabled": "auto",
"initial_scale_power": 16,
"loss_scale_window": 1000
},
"scheduler": {
"type": "WarmupLR",
"params": {"warmup_min_lr": "auto", "warmup_max_lr": "auto", "warmup_num_steps": "auto"}
},
"activation_checkpointing": {
"enabled": true,
"partition_activations": true,
"contiguous_memory_optimization": true
},
"gradient_accumulation_steps": "auto",
"train_micro_batch_size_per_gpu": "auto"
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ZeRO Stage3会对参数、梯度、优化器状态全部分片,并支持卸载到CPU内存,可在有限显存下训练超大模型;通信开销略高,适合优先保证“能跑起来”的场景。
# 5.4.3 训练代码
创建train_full.py,全参微调不使用量化与LoRA,学习率设置更低:
import torch
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForCausalLM
from trl import SFTTrainer, SFTConfig
LOCAL_MODEL_PATH = "/root/autodl-tmp/pretrained/Qwen/Qwen3-8B"
# 加载完整FP16模型
model = AutoModelForCausalLM.from_pretrained(
LOCAL_MODEL_PATH,
trust_remote_code=True
)
tokenizer = AutoTokenizer.from_pretrained(LOCAL_MODEL_PATH, trust_remote_code=True)
# 数据集处理(与前文一致,省略重复代码)
# formatted_dataset = ...
trainer = SFTTrainer(
model = model,
processing_class = tokenizer,
train_dataset = formatted_dataset,
args = SFTConfig(
dataset_text_field = "text",
deepspeed = "ds_config/deepspeed_stage_3_config.json", # 传入DeepSpeed配置
per_device_train_batch_size = 8,
gradient_accumulation_steps = 8,
warmup_steps = 100,
num_train_epochs = 1,
learning_rate = 3e-5, # 全参微调学习率远低于LoRA
logging_steps = 1,
optim = "adamw_8bit",
weight_decay = 0,
lr_scheduler_type = "constant_with_warmup",
save_total_limit = 1,
seed = 3407,
output_dir = "./outputs",
report_to = "none"
),
)
trainer.train()
# 保存完整微调模型
trainer.save_model("/root/autodl-tmp/outputs/Qwen3-8B-sft-full")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 5.4.4 启动分布式训练
使用deepspeed命令启动4卡并行训练:
deepspeed --num_gpus=4 train_full.py
# 5.5 零代码微调:LLaMA-Factory实战
LLaMA-Factory是当前工业界最流行的一体化微调平台,支持上百种开源模型、十余种微调算法,提供可视化WebUI,无需编写代码即可完成全流程微调,适合业务快速落地与非算法开发者使用。
# 5.5.1 安装部署
# 下载源码
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
# 创建环境
conda create -n llama_factory python=3.10
conda activate llama_factory
# 安装依赖
pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 --index-url https://download.pytorch.org/whl/cu126
pip install -e ".[torch,metrics]" --no-build-isolation
# 验证安装
llamafactory-cli version
2
3
4
5
6
7
8
9
10
11
12
13
14
# 5.5.2 启动WebUI
# 前台启动
llamafactory-cli webui
# 后台常驻启动
nohup llamafactory-cli webui > llama_factory.log 2>&1 &
2
3
4
5
启动成功后,默认访问地址为 http://0.0.0.0:7860;云服务器需通过SSH隧道映射到本地访问。
# 5.5.3 数据集准备
LLaMA-Factory原生支持两种主流数据集格式:
1. Alpaca格式(单轮指令)
适合问答、摘要、翻译等单轮任务,每条样本包含instruction、input、output三个字段:
{
"instruction": "总结以下文本",
"input": "人工智能是快速发展的技术领域...",
"output": "AI是一门快速发展的技术学科"
}
2
3
4
5
2. ShareGPT格式(多轮对话)
适合聊天机器人、客服等多轮场景,通过conversations列表存储对话,用role区分用户与助手:
{
"conversations": [
{"role": "user", "content": "法国首都是哪里?"},
{"role": "assistant", "content": "法国的首都是巴黎。"}
]
}
2
3
4
5
6
自定义数据集接入流程:
将整理好的JSONL数据集拷贝到
data目录;修改
data/dataset_info.json,添加数据集配置:"my_custom_dataset": { "file_name": "my_data.jsonl", "formatting": "sharegpt", "columns": {"messages": "conversations"}, "tags": { "role_tag": "role", "content_tag": "content", "user_tag": "user", "assistant_tag": "assistant" } }1
2
3
4
5
6
7
8
9
10
11刷新WebUI即可在数据集列表中看到自定义数据,支持在线预览样本。
# 5.5.4 可视化训练
在WebUI中完成以下配置即可一键启动训练:
- 模型设置:选择基础模型、模型路径、量化方式(4bit/8bit/全精度);
- 训练设置:选择训练方法(LoRA/QLoRA/全参微调)、配置超参数(学习率、批次大小、训练轮数);
- 数据集设置:勾选目标数据集,设置最大序列长度;
- 点击「开始训练」,页面可实时查看损失曲线、训练日志与显存占用。
# 5.6 本章小结
本章覆盖了LLM微调的三类主流落地方案,各自定位与适用场景清晰区分:
- 单卡LoRA微调(Unsloth):入门首选,24GB消费级显卡即可运行,速度快、成本低,适合快速验证方案、中小规模数据定制;
- 原生Transformers+PEFT:标准技术栈,灵活可控、兼容性强,适合算法研究与深度定制开发;
- DeepSpeed全参数微调:效果上限最高,适合算力充足、需要深度定制模型能力的企业级场景;
- LLaMA-Factory零代码微调:开箱即用,无需编码,覆盖全流程工具链,适合业务团队快速落地与批量实验。
对于新手开发者,建议从QLoRA单卡微调起步,先跑通完整流程,再逐步优化数据质量、调整超参数;当效果达到瓶颈后,再评估是否升级到全参数微调或更大尺寸的基础模型。
# 第 6 章 模型部署与评估
完成模型微调只是第一步,要让模型真正落地到业务中,还需要经过服务化部署和效果评估两个核心环节。本章将介绍工业界最主流的两套工具:用于高吞吐推理部署的 vLLM,以及用于一站式模型评测的 EvalScope,带你走完从模型到可用服务的完整闭环。
# 6.1 vLLM 模型部署
# 6.1.1 简介
vLLM 是由加州大学伯克利分校 Sky Computing Lab 发起的开源推理框架,也是当前工业界应用最广泛的 LLM 服务化方案之一。和侧重本地轻量化部署的 Ollama 不同,vLLM 主打服务端高并发场景,针对 GPU 推理做了深度优化,同等硬件下吞吐量相比原生 Transformers 可提升数倍甚至一个数量级。
- 项目主页:https://docs.vllm.ai/en/latest/index.html (opens new window)
- 开源地址:https://github.com/vllm-project/vllm (opens new window)
vLLM 的高性能来源于几项核心技术创新:
- PagedAttention 内存管理 借鉴操作系统虚拟内存的分页思想,把 Attention 的 KV 缓存切分为固定大小的“内存页”,按需分配与释放。彻底解决了传统 KV 缓存的内存碎片化问题,显存利用率大幅提升,是 vLLM 最核心的竞争力。
- 连续批处理(Continuous Batching) 传统静态批处理需要等一整批请求全部生成完毕才能处理下一批,GPU 大量时间在等待慢请求。连续批处理以 Token 为粒度动态调度,每生成一步就移出已完成请求、补入新请求,让 GPU 始终保持高负载,显著提升整体吞吐。
- 全栈内核优化 深度集成 FlashAttention、FlashInfer、TRT-LLM 等高效注意力内核,支持 FP8、INT4、AWQ、GPTQ 等多种量化方案,计算速度和显存占用同时优化。
- 完备的生态兼容 无缝兼容 HuggingFace 上的 200+ 主流模型架构,原生提供 OpenAI 兼容的 HTTP 接口,可直接对接 LangChain、LlamaIndex 等上层应用框架,同时支持多卡并行、多 LoRA 服务、前缀缓存等高级特性。
# 6.1.2 安装
vLLM 官方推荐 Linux 环境,Python 版本支持 3.9 ~ 3.12,推荐使用 Conda 管理虚拟环境。
# 创建并激活环境
conda create -n vllm_env python=3.11
conda activate vllm_env
# 安装 vLLM(国内可使用清华源加速)
pip install vllm -i https://pypi.tuna.tsinghua.edu.cn/simple
# 验证安装
pip show vllm
2
3
4
5
6
7
8
9
# 6.1.3 启动推理服务
vLLM 提供了开箱即用的 OpenAI 风格 API 服务,一条命令即可完成模型部署。
# 基础启动
vllm serve /root/autodl-tmp/models/Qwen3-8B-sft-all \
--served-model-name Qwen3-8B-sft-all \
--max-model-len 32K
2
3
参数说明:
--served-model-name:API 调用时的模型标识,可自定义,无需与模型文件名一致。--max-model-len:模型支持的最大上下文长度。注意单位约定:小写k代表 1000,大写K代表 1024。
# LoRA 适配器部署
如果是“基础模型 + LoRA 适配器”的轻量化微调模型,可通过参数动态加载,无需提前合并权重:
vllm serve /root/autodl-tmp/models/Qwen3-8B-base \
--served-model-name Qwen3-8B-lora \
--enable-lora \
--lora-modules adapter_v1=/root/autodl-tmp/outputs/lora_adapter
2
3
4
# 生产环境后台运行
正式部署时建议后台运行并留存日志:
nohup vllm serve /root/autodl-tmp/models/Qwen3-8B-sft-all \
--served-model-name Qwen3-8B-sft-all \
--max-model-len 32K \
--api-key your_secret_key \
> vllm.log 2>&1 &
2
3
4
5
生产环境建议通过
--api-key设置访问密钥,保障服务安全。多卡场景可添加--tensor-parallel-size N开启张量并行。
更多启动参数可参考官方文档:https://docs.vllm.ai/en/stable/cli/serve.html#modelconfig (opens new window)
# 6.1.4 服务调用
vLLM 完全兼容 OpenAI 接口协议,支持多种方式调用。
# 方式1:curl 快速验证
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen3-8B-sft-all",
"messages": [
{"role": "system", "content": "你是个乐于助人的助理。"},
{"role": "user", "content": "我的猫死了,我很难过。"}
]
}'
2
3
4
5
6
7
8
9
# 方式2:OpenAI SDK 调用
pip install openai -i https://pypi.tuna.tsinghua.edu.cn/simple
from openai import OpenAI
# 连接本地 vLLM 服务
client = OpenAI(
base_url="http://localhost:8000/v1/",
api_key="none" # 未设置密钥时可填占位符
)
response = client.chat.completions.create(
model="Qwen3-8B-sft-all",
messages=[
{"role": "user", "content": "量子计算对RSA加密的威胁与应对策略,请展示你的推理过程"}
],
extra_body={
"chat_template_kwargs": {"enable_thinking": False} # 控制是否启用思考模式
}
)
print(response.choices[0].message.content)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 方式3:LangChain 集成
pip install langchain-core langchain-openai -i https://pypi.tuna.tsinghua.edu.cn/simple
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
llm = ChatOpenAI(
model="Qwen3-8B-sft-all",
base_url="http://localhost:8000/v1/",
api_key="none",
temperature=0
)
messages = [
SystemMessage(content="你是一个专业的技术助手,回答需简洁准确"),
HumanMessage(content="LangChain如何调用OpenAI风格的大模型?")
]
response = llm.invoke(messages)
print(response.content)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 6.2 EvalScope 模型评估
模型部署上线前,需要从能力质量和服务性能两个维度做全面评估。EvalScope 是阿里魔搭社区推出的一站式大模型评测框架,覆盖从基准测试、性能压测到结果可视化的全流程,是国内开发者最常用的评测工具之一。
- 项目官网:https://evalscope.readthedocs.io/zh-cn/latest/index.html (opens new window)
- 开源地址:https://github.com/modelscope/evalscope (opens new window)
它的核心能力包括:
- 内置 MMLU、CMMLU、C-Eval、GSM8K、LiveCodeBench 等数十个主流基准数据集,覆盖知识、推理、代码、工具调用等维度。
- 支持本地模型评测与在线服务评测两种模式,可直接对接 vLLM 部署的服务。
- 内置性能压测工具,一键输出吞吐、延迟、首 Token 时间等核心指标。
- 提供 Web 可视化界面,支持多模型横向对比与报告导出。
# 6.2.1 安装
EvalScope 采用模块化设计,可按需安装不同功能组件。
# 创建并激活环境
conda create -n evalscope python=3.11
conda activate evalscope
# 安装基础版(仅原生评测后端)
pip install evalscope
# 按需安装扩展组件
pip install 'evalscope[opencompass]' # 集成 OpenCompass 评测后端
pip install 'evalscope[vlmeval]' # 多模态模型评测
pip install 'evalscope[rag]' # RAG 系统评测
pip install 'evalscope[perf]' # 服务性能压测模块
pip install 'evalscope[app]' # 可视化 Web 界面
# 一键安装全部模块
pip install 'evalscope[all]'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 6.2.2 服务性能压测
通过 perf 子命令可以对 vLLM 等推理服务做压力测试,模拟真实并发场景,输出完整的性能报告。
evalscope perf \
--url "http://127.0.0.1:8000/v1/chat/completions" \
--parallel 5 \
--model Qwen3-8B-sft-all \
--number 20 \
--api openai \
--dataset openqa \
--stream
2
3
4
5
6
7
8
核心参数说明:
| 参数 | 含义 |
|---|---|
--url | 被测模型服务的接口地址,此处为本地 vLLM 的聊天接口 |
--parallel | 并发请求数,模拟同时在线的用户数量,数值越大压测强度越高 |
--number | 总请求数量,配合并发数分多轮发送 |
--api | 接口协议类型,openai 表示遵循 OpenAI 格式规范 |
--dataset | 压测使用的数据集,openqa 为开放问答样本集 |
--stream | 启用流式响应模式,模拟打字机效果的真实场景 |
压测报告会输出多维度指标,核心指标解读如下:
基础统计
| 指标 | 含义 |
|---|---|
| Time taken for tests | 压测总耗时 |
| Succeed / Failed requests | 请求成功与失败数量 |
吞吐性能
| 指标 | 含义 |
|---|---|
| Output token throughput | 每秒生成的输出 Token 数,最核心的吞吐指标 |
| Request throughput | 每秒处理的请求数 |
延迟分析
| 指标 | 含义 |
|---|---|
| Average latency | 单请求平均总耗时 |
| Average time to first token | 首 Token 延迟(TTFT),决定用户体感响应速度 |
| Average time per output token | 每个输出 Token 的平均生成间隔 |
# 6.2.3 模型能力评估
除了性能压测,EvalScope 还可以对模型的知识、推理、代码等能力做量化评估,支持标准基准数据集与自定义数据集两种模式。
以下示例对接已部署的 vLLM 服务,使用 Qwen3 专用评测集进行能力测试:
数据集地址:https://modelscope.cn/datasets/modelscope/EvalScope-Qwen3-Test/summary (opens new window)
from evalscope import TaskConfig, run_task
task_cfg = TaskConfig(
# 被测模型名,需与 vLLM 启动时的名称一致
model='Qwen3-8B-sft-all',
# 被测服务地址
api_url='http://127.0.0.1:8000/v1/chat/completions',
# 评测模式:service 表示评测在线服务
eval_type='service',
# 使用的评测数据集
datasets=['data_collection'],
dataset_args={
'data_collection': {
'dataset_id': 'modelscope/EvalScope-Qwen3-Test',
'filters': {'remove_until': ''} # 过滤思考过程,只评估最终答案
}
},
# 批处理大小,提升评测速度
eval_batch_size=128,
generation_config={
'max_tokens': 30000,
'temperature': 0.6,
'top_p': 0.95,
'top_k': 20,
},
timeout=60000,
stream=True,
limit=200, # 快速验证可限制样本量,正式评测可去掉
)
run_task(task_cfg=task_cfg)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
如果需要评测自定义业务数据集,可参考官方文档进行格式适配:https://evalscope.readthedocs.io/zh-cn/latest/advanced_guides/custom_dataset/llm.html#qa (opens new window)
# 6.2.4 Web 可视化查看结果
EvalScope 提供了可视化 Web 界面,用于直观查看评测报告、做多模型对比。
# 确保已安装可视化依赖
pip install 'evalscope[app]'
# 启动可视化服务
evalscope app
2
3
4
5
服务默认运行在服务器本地的 7860 端口。如果使用云服务器,需要通过 SSH 隧道将端口映射到本地浏览器访问,端口映射逻辑如下图所示:
在本地终端执行端口映射命令(将端口与主机地址替换为你的服务器信息):
ssh -CNg -L 7860:127.0.0.1:7860 root@connect.bjc1.seetacloud.com -p 30119
映射完成后,本地浏览器访问 http://localhost:7860 即可打开评测可视化平台。界面支持查看单模型详细报告、多模型横向对比、各维度得分雷达图等,示例如下:

# 本章小结
模型从训练到落地遵循“微调 → 部署 → 评估 → 迭代”的闭环流程:
- 部署侧:vLLM 凭借 PagedAttention 与连续批处理技术,成为当前生产环境高吞吐部署的首选方案,兼容 OpenAI 生态,接入成本极低。
- 评估侧:EvalScope 同时覆盖“能力质量”与“服务性能”两大评测维度,内置丰富的基准数据集与可视化工具,是国内开发者做模型验收的主流选择。
在实际项目中,建议先通过 EvalScope 压测确定服务的并发承载能力,再通过业务数据集验证模型效果,达标后再正式上线。
# 第 7 章 附录:核心技术数学推导
本附录补充正文中涉及的旋转位置编码(RoPE)与低秩适配(LoRA)的核心数学推导,面向AI开发从业者,侧重原理理解与工程意义,不做纯数学层面的拓展。
# 7.1 RoPE 旋转位置编码公式推导
RoPE(Rotary Position Embedding)是当前主流开源大模型(Llama、Qwen、DeepSeek 等)普遍采用的位置编码方案。它的核心思想是:不直接向词向量中叠加位置信息,而是通过旋转矩阵对每个位置的 Query、Key 向量做角度旋转,让 Attention 点积计算天然携带相对位置关系。
我们从最基础的二维向量旋转出发,逐步推导其核心性质。
# 7.1.1 二维旋转矩阵基础
二维平面中,向量绕原点的旋转是一个标准的线性变换,可以通过矩阵乘法实现。

设有二维向量 ,其模长为 ,与 x 轴的夹角为 。根据极坐标与直角坐标的对应关系,可将向量分量写为:
将该向量绕原点逆时针旋转 ,得到新向量 。旋转不改变向量模长,因此新向量的模仍为 ,与 x 轴的夹角变为 ,对应分量为:
代入三角函数和角公式:
展开并整理,消去 后得到旋转前后坐标的关系:
写成矩阵乘法形式:
其中中间的二维矩阵就是标准旋转矩阵,记为:
工程意义:RoPE 就是把词向量两两分组,对每一组二维分量都乘以对应位置的旋转矩阵,从而给整个向量注入位置信息。
# 7.1.2 旋转矩阵的叠加性
旋转操作具备一个对 RoPE 至关重要的性质:连续多次旋转,等价于一次角度相加的旋转。
若向量先旋转 ,再旋转 ,则整体变换为两个矩阵依次相乘:
根据角度的可加性,两次旋转的总效果等价于一次旋转 ,因此有:
工程意义:这是 RoPE 相对位置不变性的数学根源。
位置 的向量旋转角度为 ,位置 的向量旋转角度为 ;两者做点积时,最终结果只和角度差 相关,也就是只和相对位置差有关,和绝对位置无关。这让模型在不同长度的文本中,对位置关系的认知保持一致。
# 7.1.3 旋转矩阵的正交性
将旋转矩阵 做转置,得到:
再写出角度取反的旋转矩阵 ,代入 、,可得:
两者完全相等,即:
同时容易验证 (单位矩阵),说明旋转矩阵是正交矩阵。
工程意义:正交变换不改变向量的模长,因此 RoPE 不会放大或缩小词向量的数值尺度,不会干扰 Attention 的原始分布,训练过程更稳定。
# 7.2 LoRA 低秩适配数学基础
LoRA(Low-Rank Adaptation)是参数高效微调的主流方案,核心假设是:大模型微调过程中,权重的更新量本质是低秩的。基于这个假设,我们可以用两个小矩阵的乘积来近似完整的权重更新,从而把训练参数量降低几个数量级。
# 7.2.1 矩阵的秩
矩阵的秩(Rank)定义为矩阵中线性独立的列向量(或行向量)的最大个数,它代表了矩阵包含的独立信息量。秩越低,矩阵的冗余度越高。
举例:
- 矩阵 ,第二列是第一列的 2 倍,两列线性相关,因此秩为 1。
- 矩阵 ,两列线性无关,因此秩为 2。
# 7.2.2 低秩分解
对于一个 的矩阵 ,如果它的秩 远小于矩阵的维度,即 ,我们就称它为低秩矩阵。
线性代数中有一个核心结论:任何秩为 的矩阵,都可以分解为两个更小矩阵的乘积。 即存在 的矩阵 和 的矩阵 ,使得:
这个过程称为低秩分解,如下图所示:

工程意义:低秩分解最直观的价值是大幅压缩参数量。
以 7B 模型的注意力层为例,权重维度为 ,总参数量约 1677 万;
如果用秩 做低秩分解,两个小矩阵的参数量为 ,仅为原矩阵的 0.39%。
这就是 LoRA 能用单张消费级显卡完成 7B 模型微调的数学本质。
# 7.2.3 LoRA 的权重更新形式
在 LoRA 微调中,我们冻结原始预训练权重 ,不直接更新它;而是额外训练一对低秩矩阵 和 ,用它们的乘积来表示权重的更新量 。
最终前向计算的输出为:
训练完成后,可以将 直接合并到原始权重 中,得到最终的微调后权重。推理时和原模型结构完全一致,没有任何额外计算开销。
补充说明:本附录仅覆盖正文核心技术的基础推导,更深入的 RoPE 复数形式、LoRA 最优秩选择、QLoRA 量化误差分析等内容,可参考对应原始论文做进一步研究。

