资讯动态

大模型训练、微调与推理:显存优化、LoRA及主流推理框架选型实战

发布时间:2026/9/8 16:39:05 来源:尧图企业网站定制
聊大模型总绕不开“训练、微调、推理”这三个词。但说实话大部分初学者的理解都停在“训练是把模型炼出来微调是让模型更听话推理是让模型跑起来”这种表面层面。真正拿着显卡上手干一轮之后你会发现这三个阶段对显存的需求、对代码架构的要求、对硬件配置的敏感度完全不是一回事。有人一张RTX 4090就敢微调7B模型也有人拿着八卡A100集群训了个寂寞——差别不在钱多钱少而在对底层机制的理解深度。这篇文章不打算给你背诵式的概念科普。我想从底层存储和计算的角度把训练、微调、推理这条链路拆开揉碎讲清楚显存到底去哪了、参数量怎么影响硬件选型、为什么LoRA能省那么多显存但精度却不一定差再把目前主流的推理框架vLLM、Ollama、llama.cpp、TensorRT-LLM这些放在同一条基准线上对比最后给出一份可以直接照抄的工程落地路径。内容偏实战但原理部分我会尽量讲透毕竟不知道“为什么”的人换一个场景就不知道怎么调参了。1. 先把概念钉死训练、微调、推理各解决什么问题1.1 三个词背后的生产流程差异从工作流角度看训练、微调、推理是流水线上的三个工位但它们的目标函数完全不同。训练预训练是从零开始学习语言规律输入是海量无标注文本通过自回归方式预测下一个token让模型学会“话应该怎么说”。这个阶段烧的是大规模算力7B量级的模型在数百张GPU上动辄训练数周普通团队基本碰不起所以行业里真正做预训练的团队非常少大部分人都不会碰这一环。微调是在已训练好的基座模型上做“定向改造”让模型学会“特定的说法方式”或“特定领域的知识”。输入是结构化的指令数据比如“问题是X标准回答是Y”这样的配对样本。这个阶段是绝大多数工程师和研究者真正会参与的工作也是显存焦虑最集中的地方。推理是微调之后的结果落地输入用户问题模型实时生成回答。这个阶段看似最简单但在线业务的延迟和吞吐要求会让它变成一个纯粹的工程优化问题怎么把模型塞进显存怎么提高并发怎么降低首token延迟。这三者的关系可以用一个类比理解训练相当于一个学生从小学一路读到大学毕业微调相当于去公司上班前的岗前培训推理则是正式上岗后每天处理具体工作。同样是“用到这个人的能力”成本差了一个数量级。1.2 一张表讲透三者的本质差异很多人分不清微调和推理的显存差异根源在于不理解一个关键事实训练不仅要存模型还要存优化器状态、梯度和前向过程的激活值推理只需要存模型本身。维度预训练微调推理目标学习通用语言知识适配特定任务/风格实时响应用户请求数据海量无标注文本TB级少量标注指令数据MB~GB级无固定数据实时输入显存占用权重梯度优化器状态激活值取决于全量还是LoRA仅权重KV Cache算力需求数千GPU·天单卡~数十卡·小时首延迟/吞吐优化时间周期数周~数月数十分钟~数天毫秒~秒级响应核心瓶颈带宽与集群稳定性显存容量与过拟合风险延迟、并发、量化损失这张表格里最值得深入理解的是显存那一行。预训练和全量微调之所以显存爆炸是因为优化器状态AdamW要存参数的一阶动量和二阶动量和梯度本身都是和模型参数同量级的数据。而推理没有这些额外开销只需要模型权重和逐渐累积的KV Cache。1.3 为什么总有人把微调和推理混为一谈我把话放这凡是问“怎么用Ollama微调模型”的人大概率还没分清楚“加载模型”和“训练模型”的区别。Ollama是个推理框架它可以加载别人训练好的模型也能跑你微调完导出的GGUF文件但它自身不自带训练能力。AnythingLLM同理它是知识库应用核心是RAG检索增强生成不是模型训练。这个混淆局面其实完全可以理解因为大模型的工具链链条太长了训练用DeepSpeed/Megatron微调用Llama-Factory/ms-swift权重转换用transformers/mergekit量化用bitsandbytes/llama.cpp推理用vLLM/Ollama/TensorRT-LLM。工具越多边界越模糊。我见过不止一个朋友买了张4090下载个Ollama跑通了对话就以为自己“部署了大模型”然后问怎么微调。我的建议是想微调就别在Ollama上死磕直接用支持训练的工具链Llama-Factory上手的体验比在Ollama里改造好太多。做技术选型的第一步永远是先明确你现在处于流水线的哪个工位。2. 底层机制为什么大模型对显存这么贪婪2.1 从“乘法”和“存储”角度看模型运转理解大模型的显存占用只需要抓住两件事参数要存储计算要搬运。参数存储很好理解。模型文件本身有多大加载就会占多少显存。以7B模型为例用FP16半精度每个参数占2字节存储权重文件大小就是 7×10⁹ × 2字节 14GB。这意味着哪怕只做推理一张显存低于14GB的显卡跑7B模型也已经非常紧张因为除了权重前向计算时还会产生KV Cache。计算搬运则需要理解Transformer的前向过程。输入一段文本模型要做的是token embedding查找 → 多层Decoder Block每个Block包含自注意力、前馈网络、LayerNorm → 输出层产生概率分布。每一层都要把权重从显存读入计算单元矩阵乘法的中间结果激活值也要临时驻留在显存。层数越深、序列越长激活值越大。这个“搬运”过程解释了为什么大模型计算那么贵它不是算一次而是每个token都要跑一遍完整的前向网络。训练时还会多一遍反向传播反传也要计算梯度所以训练的计算量大约是推理的三倍。2.2 显存到底花哪里了我给训练时的显存账本列一个清单按占用大小排序优化器状态AdamW优化器对每个参数要保存两个动量变量FP32精度下每个参数占8字节。7B模型全参训练时仅这一项就是56GB。梯度每个参数对应一个梯度FP16/FP32混合精度下按2字节算7B模型就是14GB。模型权重FP16下7B模型权重14GB但混合精度训练中会额外维护一份FP32主权重28GB用于参数更新时的数值稳定性。激活值前向过程每层输出的中间结果。这部分大小和batch size、序列长度强相关。训练时为了反向传播必须保留激活值批量越大、序列越长开销越夸张。推理时账本瞬间缩水权重14GB KV Cache若干GB。KV Cache每层都要缓存每个已生成token的Key和Value向量它的大小约为 2 × 层数 × 注意力头数 × 头维度 × 序列长度 × 2字节序列越长开销越大。提示所以你会看到很多模型仓库同时给出“最低显存”和“推荐显存”前者是按量化权重短序列算的后者是考虑实际多轮对话和长上下文后的保守值。2.3 算个账7B模型全参训练为什么这么夸张我们用7B模型做全参微调混合精度训练batch size为1序列长度2048粗略算一下。模型权重FP16权重FP32主权重14GB 28GB 42GB梯度14GB优化器状态56GB激活值按7B量级、单条序列2048长度估算大约8~16GB光这几项加起来就是120GB以上这还没算CUDA context、临时buffer和显存碎片。这就是为什么一张4090的24GB显存根本跑不了7B模型全参微调而LoRA之所以能跑是因为它不需要为全部参数保存梯度和优化器状态只训练几十万到几百万个小规模低秩矩阵训练参数量可能只有全模型的0.1%1%。这个账算明白之后你就理解为什么QLoRA能在24GB单卡上微调65B模型4bit量化权重把14GB瘦身到3.5GB左右LoRA把梯度和优化器状态限制在小矩阵上激活值用gradient checkpointing换取更少显存。省下来的空间全部留给了模型本身。3. 训练大模型到底在炼什么3.1 预训练、后训练、增量训练三个容易被绕晕的环节预训练是让模型学会语言本身数据量大、成本高、训练时间以周为单位。现在主流开源模型如Qwen系列、Llama系列的预训练权重已经公开大家直接用就好不需要自己重复烧钱。后训练是基座模型变成“能用”的关键环节。基座模型只会续写不具备“人类偏好对齐”能力所以需要SFT监督微调和RLHF/DPO人类反馈优化这些后训练手段。这也是行业里“微调”这个词最常指向的阶段。增量训练继续预训练是在预训练基础上用额外的领域语料继续学习和更新让模型掌握某个垂直领域的术语和知识。它和SFT的区别是增量训练用的是无标注精英文本如论文、病历、法律文书目标是补充知识SFT用有标注的指令样本目标是学会“该怎么回答”。我在实际项目中经常把两者串行使用先增量训练补充领域知识再SFT教会格式和交互方式。3.2 数据管线和loss设计训练质量和数据质量强相关这是我在实战中体会最深的一条。做微调之前先花至少三分之一的时间清洗和格式化数据收益远大于调参。以SFT为例一条标准训练样本长这样{ instruction: 解释一下什么是反向传播, input: , output: 反向传播是一种通过链式法则逐层计算损失函数对每个参数梯度的算法是深度学习训练的核心机制…… }训练时模型输入是指令部分目标输出是标准答案部分loss只计算在答案token上的交叉熵指令部分的loss会被mask掉。这个设计让模型学到“看到指令生成对应答案”的映射而不是把问题和答案一股脑全背下来。数据数量方面几千条高质量数据就能让一个小模型学会一种风格但要让模型稳定记住大量领域知识则可能需要几万到几十万条。数据质量优先于数量、多样性优先于重复这是铁律。3.3 分布式训练的三种并行方式单卡放不下模型时分布式训练就上场了。三种主流并行方式数据并行DP/FSDP每张卡存一份完整模型数据切分成多个batch分别计算然后同步梯度。适合模型本身能放进单卡显存但想加速训练的场景。DeepSpeed ZeRO技术把模型状态权重、梯度、优化器分片到多卡解决了单卡内存不够的问题。张量并行TP把一层内的大矩阵乘法切分到多张卡上并行计算每张卡只处理权重的一部分。Megatron-LM是最典型的实现。它要求卡之间高带宽连接NVLink跨机性能会急剧下降。流水线并行PP把模型的层切成多段GPU间的计算像流水线一样传递。用一张卡计算第1~8层另一张卡计算第9~16层。对卡间带宽要求比TP低但存在流水线气泡部分显卡等待问题。实际工程中通常混合使用跨机器用PP/DP机器内部用TP。对小规模团队来说最常见的方案是单机多卡用DeepSpeed ZeRO-3/Fully Sharded Data Parallel既能分片又能节省显存配置相对简单。4. 微调不是“再训练一遍”三种流派深度对比4.1 全量微调最彻底也最贵全量微调Full Fine-tuning更新模型中所有参数让上层适应任务的能力最强某个领域的语料风格可以被学得最充分。但代价也很直接显存需求几乎和预训练一样高需要保存全部参数的梯度、优化器状态和前向激活值。以小钢炮模型Qwen2.5-7B为例全参微调单卡A100 80GB只能塞下batch size很小的情况多卡还要做ZeRO分片。中小团队如果没有A100/H100集群这条路基本走不通。它适合的是“已经确定要在某个领域长期深耕且算力预算充足”的场景比如大厂内部的垂直领域模型。4.2 Freeze微调冻结一部分参数Freeze微调把大部分底层参数固定住只更新靠近输出层的部分参数。思路是底层学到的是通用语言表示词法、句法这些知识是跨领域通用的不需要改顶层学习的是语义和输出分布更接近目标任务值得更新。冻结参数的好处是能减少需要保存的梯度和优化器状态。坏处是它没有一个类似LoRA的“低秩重参数化”那些被冻结的层对领域新知识的表达能力受限。实战中我很少单独用Freeze它更适合作为基线对比——当年BERT时代它是主流现在大模型时代LoRA基本替代了它的位置。4.3 LoRA用低秩逼近切走大半成本LoRALow-Rank Adaptation是我最推荐中小团队选择的方案。它基于一个观察全量微调时权重更新的矩阵往往是低秩的因此可以用两个小矩阵A和B的乘积来近似增量矩阵 ΔW B × A。实际做法是冻结原始权重W在旁边添加一个旁路分支训练时只更新A和B这两个小矩阵。最终推理时可以把训练好的增量矩阵合并回原始权重也可以在不修改原权重的情况下动态加载LoRA适配器。以7B模型为例如果设定LoRA的秩rank为16作用在attention层的q/k/v/o投影和FFN层上可训练参数量通常只有总量的0.1%~1%。省下来的不只是存储更是梯度和优化器状态——这才是显存大头。QLoRA是LoRA的进一步扩展先把基础模型量化到4bit再在量化权重上挂LoRA训练。这使得单张24GB显卡训练7B模型变得非常轻松甚至能跑33B级别的模型。代价是训练速度比FP16的LoRA略慢且量化权重的精度限制在某些任务上会体现为轻微效果损失。4.4 实战选型经验与显存估算微调方式7B模型显存估算是否单卡24GB可训适用场景全量微调120GB否有A100/H100集群深度领域改造Freeze微调60~80GB紧张算力有限但想要一定灵活性LoRAFP1620~26GB勉强/可以绝大多数领域的通用方案QLoRA4bit8~16GB轻松显存紧张或想挑战更大模型我的经验是第一步永远先用QLoRA跑通流程验证数据质量和效果趋势如果效果不错再决定要不要升级到LoRA或者全量微调。这样能最快速度产出可评估的结果而不是一上来就烧满全量训练的算力。5. 实操用Llama-Factory跑一次QLoRA微调Llama-Factory是我目前最推荐的微调开源工具它对新手友好、支持模型多、还内置了WebUI界面和大模型自动评测功能。下面是它的实操步骤照着做基本不会翻车。5.1 环境准备与安装推荐用Python 3.10和CUDA环境一张16GB以上显存的显卡足够。# 创建虚拟环境 conda create -n llama-factory python3.10 conda activate llama-factory # 安装PyTorch按官网选对应CUDA版本 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # 安装Llama-Factory git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e .[torch,bitsandbytes]安装bitsandbytes是为了QLoRA的4bit量化。如果安装后遇到“CUDA Setup failed”这类报错多半是bitsandbytes版本和CUDA版本不匹配导致的重装对应版本就行。5.2 数据准备JSON格式是命门Llama-Factory支持的数据格式中我只推荐最通用的sharegpt和alpaca格式。alpaca格式是这样的[ { instruction: 写出这段代码的注释print(hello), input: , output: print是Python内置函数作用是在控制台输出括号内的内容…… } ]把数据放在data/目录下然后在data/dataset_info.json中注册数据集的路径和格式。很多人栽在这里注册信息写错菜单里根本看不到自己的数据集。记得注册时确认“format”字段是“alpaca”不要想当然写成其他名字。5.3 训练一键启动WebUIpython src/train_web.py浏览器打开提示的地址在界面里选择模型名称如Qwen2.5-7B-Instruct设置以下关键参数微调方法lora量化等级4bit学习率2e-4LoRA常用训练轮数3数据量大则减少计算精度bf16Ampere架构以上推荐最大序列长度2048长文本另说Fold 2500步左右再跑。训练完成后界面会生成一个包含adapter_config.json和adapter_model.safetensors的LoRA文件夹。5.4 导出合并与部署训练得到的LoRA适配器有两个用途直接合并回模型python src/export_model.py \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --adapter_name_or_path ./output/lora_model \ --export_dir ./merged_model \ --export_size 4 \ --export_legacy_format false合并后的模型就是一份可以直接用transformers加载的完整模型权重。保持LoRA分离需要同时加载多个风格、随时切换场景下很有用。推理时额外传一个peft_model_id参数即可from transformers import AutoModelForCausalLM from peft import PeftModel base_model AutoModelForCausalLM.from_pretrained(Qwen/Qwen2.5-7B-Instruct, device_mapauto) model PeftModel.from_pretrained(base_model, ./output/lora_model)5.5 我在Llama-Factory里踩过的坑第一个坑是关于loss曲线的。刚跑完一个epochloss降到1.2左右你以为已经很好了结果生成了几轮对话发现模型基本在复读。后来发现训练数据里同类别样本太多模型只是把高频答案背下来了。解决办法是保证数据类别均衡同一类问题不要超过样本总量的15%。第二个坑是学习率设置。QLoRA如果直接用默认的2e-4在小数据量场景下很容易把模型学坏灾难性遗忘表现为模型在通用能力上明显退化。后来我小数据量微调时把学习率降到1e-4甚至5e-5效果就稳定了很多。第三个坑是“改完模型不会对话了”。这通常是数据格式里的问题instruction和output拼接方式改变导致特殊token丢失。排查方法是先打印模型输入确认特殊的角色/结束token还在而不是凭肉眼猜。6. 推理是另一套工程问题6.1 为什么说训练和推理在工程上是两个世界先说结论训练在乎的是吞吐和收敛速度推理在乎的是延迟和并发能力。训练时可以把几万条样本一次性灌进去不在乎单个样本的响应速度只要单位时间处理的token总量够大就行。推理却面临完全不同的场景用户输入一句话要求几百毫秒内给出第一个token然后以每秒几十个token的速度持续输出。如果是API服务还要同时应对几十上百个并发请求。这种差异导致两者在工程实现上分道扬镳训练框架如DeepSpeed、Megatron专注模型并行与梯度同步推理框架专注KV Cache管理、连续批处理、投机采样、图优化这些延迟优化技巧。6.2 延迟和吞吐的博弈任何推理框架做性能优化本质都是在延迟和吞吐之间找平衡。延迟关注单个请求从发起到首个token返回的时间TTFT和每个token的生成间隔TPOT。吞吐关注单位时间内能完成多少请求。对在线交互场景TTFT要尽量低用户等不了太久对离线批量生成场景更看重吞吐延迟慢一点没关系。vLLM最核心的贡献是引入了PagedAttention和Continuous Batching显存中的KV Cache按页管理多个请求动态共享GPU资源空闲时可随时插入新请求这样吞吐直接比传统方案提升数倍。代价是某些极端场景下单请求延迟波动会大一些。6.3 主流推理框架怎么选框架定位优势不足适用场景vLLM高吞吐在线服务PagedAttention、连续批处理、OpenAI兼容API对量化支持不如llama.cpp丰富API服务、高并发生产环境Ollama本地一键部署安装极简、模型管理方便吞吐优化较弱不适合大规模并发个人电脑、学习体验、小型项目llama.cpp极致量化与边缘部署GGUF量化方案成熟CPU也能跑推理速度上限不如GPU专用框架低显存/无GPU环境、端侧部署TensorRT-LLM规模化生产平台针对NVIDIA GPU深度优化性能最强仅支持NVIDIA配置复杂企业生产集群我的意见很直接自己电脑上体验优先选Ollama需要做成服务给外部调用直接上vLLM要部署到没有GPU的服务器走llama.cppGGUF量化预算充足、对性能极致的生产环境再考虑TensorRT-LLM。另外AirLLM这类的单卡推理方案也值得了解它通过分层加载权重到显存可以在小显存上跑超大模型但性能基本是“能跑不能商用”的水平当玩具和学习工具还行。7. 量化中低端显卡的救星7.1 量化在做什么大模型权重默认是FP16格式每个参数占2字节。量化就是压缩参数所占的位数比如从16位压到8位、4位甚至更低从而减少模型体积和显存占用。本质是用精度换空间在高位权重上筛选关键信息。量化最主流的两种方式是训练后量化PTQ和量化感知训练QAT。PTQ直接对训练好的模型做压缩速度快但精度损失相对大QAT在训练过程中就模拟量化误差精度保持更好但成本高。当前大模型推理大多用PTQ少数对精度极其敏感的场景会考虑QAT。7.2 主流量化方案对比GGUFllama.cpp系列把模型量化成不同比特的GGUF文件从q2_k到q8_0有多个等级。q4_k_m是兼顾体积和质量的热门选择7B模型量化后大约4~5GB在消费级显卡上流畅运行。GPTQ业界主流的GPU量化方案4bit量化下7B模型约4~5GB可用显存就能轻松加载。它对GPU推理框架如vLLM、transformers支持友好但CPU推理效率一般。AWQActivation-aware Weight Quantization同样是4bit量化保护对激活值影响大的权重通道精度通常优于GPTQ在部分模型上表现很惊喜。bitsandbytes跑QLoRA时用的4bit NF4量化它和上述离线量化最大区别是“动态”——权重是以4bit驻留在显存中、计算时反量化为高精度精度保持不错但实际推理速度并不占优。7.3 量化影响微调效果吗问这个问题的人大概率是想在低显存显卡上既量化又微调。答案是分开做不要同时搞。我实测过在QLoRA训练过程中直接把基座模型量化到4bit再做LoRA训练效果大多数情况下能接受。但如果你要做全量微调或者比较精细的领域适配基线模型尽量不要用4bit量化至少用8bit或干脆FP16。原因很简单量化本身会滤掉一部分信息基座已经“看不清”了再在其上微调等于带上老花镜绣花细节容易崩。推理阶段则放心大胆用量化。只要选择质量好的量化方案AWQ、GPTQ、GGUF q4_k_m在通用对话任务上和FP16的差距肉眼几乎不可辨认但显存减半甚至更多速度反而更快。遇到量化后效果突然变差的情况先检查是不是使用了奇怪的量化等级比如q2_k这种体积极端的等级精度损失会非常明显。8. 从单卡到生产工程落地的关键选择8.1 硬件选型按需求倒推配置大模型硬件选型的第一原则是先定要跑多大参数量的模型再反推显存大小最后再算需要几张卡。推理场景比较简单。7B模型FP16需要至少16GB显存14B要24GB32B要48GB70B要140GB单卡只能靠量化。RTX 4090 24GB目前是消费级部署的甜点A100 80GB/H100 80GB是生产环境的标配如果主要用GGUF量化推理CPU单机也能跑得动7B以下模型。微调场景就复杂了。7B模型QLoRA单卡16GB起步推荐24GBLoRA单卡24GB起步推荐48GB全量微调至少80GB起步且建议用FSDP多卡分片。我见过有人用两张4090拼一个7B全量微调效果也能跑通但多卡通信效率和稳定性明显不如单张A100来得省心。8.2 推理服务从Ollama起步用vLLM上线本地体验阶段用Ollama非常舒服ollama pull qwen2.5:7b ollama run qwen2.5:7b两行命令搞定一个能对话的大模型这在新手阶段带来的成就感远超一切框架调优。但一旦你有多用户并发、需要OpenAI兼容API或有严格的令牌输出控制需求Ollama就开始露怯了。把服务切到vLLM是成熟的演进路线python -m vllm.entrypoints.openai.api_server \ --model ./merged_model \ --tensor-parallel-size 1 \ --gpu-memory-utilization 0.9 \ --max-model-len 4096 \ --served-model-name mymodel启动后就能用OpenAI SDK直接调用现有应用几乎不用改代码就能接入。8.3 落地路上的亲身教训分享几条我在工程落地中真正吃过的亏都是文档里不会写的东西。第一个教训是显存utilization不要拉满。曾经我给vLLM设了0.95的GPU显存利用率结果服务一跑满CUDA OOM把整卡都搞挂了。后来稳定在0.85~0.90给CUDA context和持久化KV Cache留了缓冲。多留5%显存少熬一个通宵这个交易划算。第二个教训是并发拉升的速度要渐进。大模型部署完直接抖进100并发延迟会瞬间暴涨各种超时告警。正确做法是先20并发观察显存和延迟趋势再50、100逐步加压。观察指标里最核心的是“单请求TPOT是否走平”一旦它随时间线性上涨就该考虑加卡或加机器了。第三个教训是输入输出长度即算力。当时做客服场景时把max context调到8192以为能覆盖所有用户输入结果线上单个请求的TTFT直接翻了一倍因为KV Cache翻了倍、prefill算力也翻了倍。后来按业务实际情况把上下文压缩到3072延迟立刻回落到可接受范围。很多性能问题不是框架问题是业务参数设计问题。动手之前先把一个问题想清楚你现在要做的到底是大模型训练、微调还是推理这个问题的答案直接决定你接下来买不买卡、用哪个工具框架、看什么文档。如果把推理当训练搞你会白白烧掉大量预算把微调当“让AI自学”你会拿数据格式的错误浪费一整天。先把目标钉死再沿着工具链往下走大模型落地其实没有想象中那么玄乎。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价