
1. 训练、微调与推理大模型落地绕不开的三座大山做了几年大模型相关的工程我越来越觉得“大模型”这个词被用得太轻松了。很多人拿开源模型跑个 demo、调两轮 prompt就觉得自己在做大模型了。但真要落到生产环境你要面对的首先是训练、微调与推理这三大环节它们各自对应着完全不同的技术栈、瓶颈和思维方式。先说训练。训练预训练是从头训练一个大模型让它在海量语料上学习语言规律、知识结构。这一步极其烧钱、烧卡、烧时间一般是头部大厂或科研机构在做普通团队极少碰。但哪怕你只是用开源权重继续做后训练也必须理解预训练时模型学会的是什么、能力边界在哪否则后面微调和部署会处处踩坑。微调则是绝大多数团队实际要做的环节。你要让通用大模型适配特定领域、特定任务比如让 Qwen 变成客服机器人、让 Llama 学会写 SQL、让视觉模型学会检测产线上的缺陷。微调的方案从全量微调到 LoRA、QLoRA 不一而足选择不同显存开销、效果上限、工业落地难度天差地别。推理框架则是最后一道关卡也是我见过最多人“栽跟头”的地方。模型微调完效果看着不错一上生产就完了显存爆了、延迟超标、并发一高直接 OOM。原因往往是推理阶段没做好量化、批处理、KV Cache 优化或者干脆选错了推理引擎。这篇文章我就把这三大环节从底层原理到工程实现串起来讲一遍重点放在真正的实操细节上什么样的场景该选全量微调、什么时候用 LoRA 就够了以及 vLLM、llama.cpp、TensorRT-LLM 这些推理框架各自的适用边界在哪里。中间也会穿插一些我实际踩过的坑和排查思路希望对正在做模型优化的朋友有帮助。2. 训练阶段的核心逻辑预训练到底在解决什么问题2.1 训练的本质是“预测下一个词”很多人第一次接触大模型训练容易被复杂的并行策略、分布式通信吓到然后开始研究各种高端东西。但我觉得第一步应该先把训练任务的本质搞清楚大模型预训练的核心目标就是根据前面的 token 序列预测下一个 token 是什么。这本质上是自监督学习不需要人工标注只要去网上爬海量文本切分成 token然后不断做“填空预测”就行。想象一下给模型输入“今天天气真”下一个词就该预测“好”。模型内部有几十亿甚至几千亿参数这些参数通过梯度下降不断调整让预测结果逐步接近真实文本分布。训练过程的 Loss 曲线通常是这样走的一开始 loss 掉得很快模型在快速学习语法和基础规律到了中后期loss 下降速度明显放缓每一点提升都要付出巨大的算力代价。这也是为什么同样规模的模型有人训练 100B token 就发论文有人要训到 3T token 才能出稳定效果——数据量、批次大小、学习率调度策略不同最终效果差别很大。预训练阶段的数据配比也很有讲究。通常不是把所有语料简单混在一起而是按照领域分布做加权采样。代码、数学、书籍、网页各自占多少比例会直接影响模型的下游能力。代码和数学比例太低模型的逻辑推理能力会偏弱全是网页语料模型写长文时容易空洞。实际工程中这些配比都是通过小规模实验摸索出来的没有一个通用公式。2.2 训练并行的三类主要策略DP、TP、PP当你真要训一个 7B 或者更大的模型单张 80GB 显卡放不下整个模型和优化器状态一个 7B 模型仅参数就要 28GBAdam 状态再加两倍就必须做分布式训练。这里最常用的三种并行策略是数据并行DP、张量并行TP和流水线并行PP。数据并行最简单每张卡放一份完整模型喂不同批次的数据训练时做梯度同步。但模型太大时单卡连模型参数都放不下DP 就失效了。张量并行则是把模型的一层拆成多份每张卡只算一部分矩阵乘法适合单机多卡场景因为卡间通信量非常大跨机器走网络带宽根本扛不住。流水线并行是把模型的 Layer 按顺序切段第 1 层到第 N 层在一张卡上第 N1 层到第 2N 层在另一张卡上数据像流水线一样一层层往下传——它把通信量降下来了但会有“空泡”问题利用率打折扣。实际训练大模型时往往不是选其中一种而是三层并行混合用。我在项目里接触过用 Megatron 框架做训练的情况7B 模型经常是 TP4、PP2、DP8 这样的组合卡多了还需要配合 ZeRO 策略做显存优化。具体怎么配比和你的集群拓扑、网络带宽、显存大小都强相关没有绝对的最优解只能反复测通信开销和计算效率找到最平衡的那组参数。2.3 显存去哪了参数、梯度、优化器状态与中间激活训练大模型时显存爆掉是日常事故。要排查显存使用你先得知道显存被谁吃了。以 7B 模型混合精度训练为例常见的显存分配大概是这样的模型参数FP16约 14GB梯度FP16约 14GBAdam 优化器状态约 42GB即 FP32 的主参数副本 28GB 加动量等状态 14GB中间激活值随 batch size 和序列长度变化可能是十几到几十 GB可以看到光模型参数、梯度和优化器状态就已经占了 70GB接近单张 A100 80GB 的极限了。这还没算中间激活值。所以训练时如果 batch size 调大一点就 OOM往往不是模型太大而是激活值炸了。解决思路也很直接一是打开梯度累积用小 batch 模拟大 batch二是用激活重计算前向传播时不保存中间结果反向传播时重新算一遍省显存但费算力三是用 ZeRO 策略把优化器状态、梯度、参数分片到多张卡上。我实际用 DeepSpeed ZeRO Stage 2 的时候有个体会7B 模型在单机 8 卡 A100 上做全量微调原本要开激活重计算才能跑起来的 batch改完 ZeRO 后可以直接翻倍。代价是多卡间梯度通信更频繁训练吞吐会有一定折损但对中小团队来说能用省下的显存把任务跑起来比什么都重要。3. 微调方案怎么选全量、Freeze 与 LoRA 的真实边界3.1 全量微调效果上限最高但成本和风险都高全量微调也叫 Full Fine-tuning就是加载预训练权重后把所有参数都设为可训练用你的数据集继续做反向传播更新。理论上这是微调方案里效果上限最高的因为模型全部参数都在适配你的任务学习容量完全释放。但全量微调的成本相当高。一是显存需求最大因为所有参数的梯度和优化器状态都要保留7B 模型全量微调单卡 80GB 基本不用想哪怕 ZeRO 或者 TP/PP 并行也要多卡才能把显存装下。二是训练时间长一个 epoch 可能要跑很久调参周期非常长。三是有灾难性遗忘风险模型训过头了原来通用的能力可能明显退化变成“偏科生”。我曾经做过一个垂直领域问答机器人的实验用几万条指令数据对 Qwen2.5-7B 做全量微调。效果是真的好专业术语回答准确率提升非常明显但训练过程中稍微把学习率调高一点超过 2e-5模型连常识问答都开始出问题。所以全量微调并不是拿来就能用的“银弹”你得有数据、有算力、有耐心调参还得准备充足的回滚方案。3.2 Freeze 微调冻结大部分参数只训一部分Freeze冻结微调的思路很简单模型绝大多数层的参数全部固定不动只训练最后的输出层或最靠近任务的那几层。这样做的好处是显存占用和训练时间大幅下降因为可训练参数少梯度计算和优化器状态都少了好几个量级。Freeze 微调的局限性在于它只调整了模型末端的表征映射无法改变模型深层的语义理解。如果任务和预训练阶段的知识分布差得不太远比如只是做情感分类、短文本标注这类任务Freeze 基本够用。但如果你的任务需要模型真正学会新领域的知识和推理模式Freeze 的效果就明显不够了。在训练策略上Freeze 微调通常会把学习率设得比全量微调高一点因为参与更新的参数少模型不容易过拟合。但也正因为参数少收敛速度会更快数据集的质量对最终效果的影响更大。我在实际项目里一般把 Freeze 作为“先跑个 baseline”的手段用来快速验证数据质量和任务可行性等确认方向没问题再考虑要不要升级到 LoRA 或全量微调。3.3 LoRA低成本微调的主流选择但要注意 Rank 的学问LoRALow-Rank Adaptation的原理是冻结原始模型权重在每一层旁路注入一个低秩分解矩阵训练时只更新这个低秩矩阵。用大白话说原模型的“大路”不动在旁边修一条“小路”来调整行为。比如你在做 Qwen2.5-7B 的 LoRA 微调设置 rank8那么每一层的低秩矩阵的实际参数量大约是hidden_size * rank * 2对于 7B 模型来说全部可训练参数大概只有几百万到一两千万不到总参数的 1%。这意味着你只需要加载权重然后训练极小一部分参数显存开销大幅下降单张 16GB 甚至 12GB 消费级显卡也能微调 7B 模型配合 4bit 量化还能更低。LoRA 的实操要点在于 Rank 的选择。Rank 太小低秩空间表达力不足模型学不动复杂任务Rank 太大可训练参数变多显存和过拟合风险都上升。我的经验是先在一个小的验证集上分别跑 rank8、16、32 三组实验对比验证集效果选择收益开始趋于平缓的那个值。对于大多数指令微调任务rank16 是一个还不错的起点。另外LoRA 的alpha参数缩放系数一般设为 rank 的 1 到 2 倍这个比例影响最终合并权重的放大倍率调的时候要和 rank 联动看。LoRA 还有一个特别实用的优势是模块化部署。同一个基座模型上你可以训练多个不同任务的 LoRA 插头比如一个是法律问答、一个是医疗问答推理时按需切换不需要同时加载多个全量模型。这在真实的生产环境里能省下大量显存和服务切换成本。3.4 到底该怎么选从场景倒推方案很多时候选哪种微调方案不取决于“哪个效果更好”而是取决于“你的场景限制了什么”。我做过的选择参考如下算力极其有限、能接受稍微降低效果优先 LoRA 4bit 量化QLoRA单卡 12GB 也能跑得动算力适中、任务效果优先、数据量万级以上LoRA 是首选效果和成本平衡得最好算力充足、任务和原模型差异很大、需要最大化能力全量微调但要严格验证通用能力下降幅度算力有限但任务非常简单分类、短文本抽取等Freeze 微调是性价比最高的选项另外要提醒一点LoRA 的效果并不是恒等于“效果差一档”。在一些领域内数据集中且质量高的实验中LoRA 的效果甚至可以追平全量微调。原因在于大模型的底层能力在预训练阶段已经基本成型微调阶段其实更像是“拨动方向盘”只调整少部分参数反而能避免全局灾难性遗忘。这个现象在很多学术论文和工程报告里都提到过值得实操时多对比验证。3.5 多卡微调时 LoRA 如何扩展很多团队过了“单卡能跑”的阶段后会想“我有多张卡能不能用 LoRA 加速训练”答案是能但要注意 LoRA 配合数据并行DP是最自然的扩展方式因为模型本身加载的内存占用不大每张卡放一份完整模型加小的 LoRA 分支没问题。真正需要关注的是梯度同步的通信开销和训练批次大小调整。我在用 4 张 A100 同时微调同一个 7B 模型时采用了 DeepSpeed 的 ZeRO Stage 2 LoRA 组合效果不错。整体训练吞吐比单卡提升了约 3 倍但显存占用每张卡只增加了很小一部分因为 LoRA 的可训练参数极少。也试过直接纯数据并行不加 ZeRO但 7B 模型每张卡都要维护一个完整的优化器状态副本显存就有点吃紧了梯度同步的开销也更高反而比 ZeRO 慢。如果你用的微调框架是 LLaMA-Factory 这类工具它内部已经做好了 LoRA 多卡支持通过--multi_gpu或python -m torch.distributed.run启动即可。像我之前的 Qwen2.5-7B LoRA 微调实战就是直接在 LLaMA-Factory 上配好 YAML 文件然后多卡并行跑起来的。这类框架最大的价值是把 LoRA 的适配层注入、保存、合并流程都封装好了训练完可以直接导出合并后的权重省去手写适配代码的麻烦。4. 推理框架的选型与部署实践别让模型“死在最后一步”4.1 推理阶段为什么还容易爆显存模型训练完你以为万事大吉了不推理阶段是另一场硬仗。很多人在训练和微调阶段花了大量精力结果部署上线时才发现推理阶段的显存和延迟问题比训练还复杂。推理时显存占用主要来自两部分一是模型权重本身二是 KV Cache。KV Cache 是自回归生成过程中缓存历史 token 的 Key 和 Value 向量的缓存块随着序列长度的增加而线性增长。以 7B 模型为例FP16 精度下模型权重就要占 14GB再加上 batch size 为 8、输出长度为 2048 的显存开销KV Cache 轻松吃掉几 GB 到十几 GB。如果不懂这些直接按训练阶段的排错思路去查可能查半天都找不到根因。推理优化的核心思路就几条权重量化、批处理、KV Cache 管理和计算图优化。下面逐个说。4.2 量化把 FP16 压到 INT8 甚至 INT4量化是推理阶段性价比最高的优化手段本质上是用更少的 bit 来表示模型权重和激活值从而减少显存占用和计算量。从 FP16 到 INT8权重体积直接减半到 INT4直接减到四分之一。显存占用下来了大批量并发就成为可能。量化分为训练后量化PTQ和量化感知训练QAT。绝大多数场景下微调好的模型直接做 PTQ 就够了常见工具是 AutoGPTQ、AutoAWQ、GPTQ 等。量化带来的精度损失通常在可接受范围内尤其是对 7B 以上规模的模型INT8 精度的损失在大多数问答任务上几乎感知不到INT4 会有一定损失但在显存紧张时非常值得尝试。实际操作中如果用的是 llama.cpp 这类框架量化位宽可以直接通过命令行指定比如-b 4就是 4bit 量化。如果是 vLLM可以在启动服务时通过--quantization awq指定量化方式并用对应的量化权重文件。我自己的经验是如果用消费级显卡比如 4080、4090跑 7B 模型INT4 量化 AWQ 是比较稳的组合显存占用能控制在 6GB 左右延迟也很低体验接近 GPTQ 的 INT4 方案但 AWQ 的激活值量化策略在一些长文本生成场景下表现更好。4.3 推理框架横评vLLM、llama.cpp、TensorRT-LLM 与 Ollama框架选型是个大话题我试着用表格把几个主流方案的适应场景捋一下这样你可以快速对齐自己的需求。框架核心优势典型场景主要局限vLLM高吞吐、PagedAttention 高效管理 KV Cache生产环境高并发的在线推理、API 服务对 GPU 架构和依赖版本要求较严格llama.cpp轻量、CPU/GPU 混合推理、量化支持极好本地单机部署、低资源环境吞吐不如 vLLM生产高并发场景弱TensorRT-LLMNVIDIA 深度优化推理延迟极低对延迟敏感、卡资源固定的线上服务部署复杂需要 TensorRT 编译和 CUDA 调优Ollama上手极简、一键运行多种开源模型本地体验、个人开发测试、边缘盒子高级配置/细粒度优化能力有限vLLM 是我在生产环境用得最多的框架。它最出彩的地方是 PagedAttention借鉴了操作系统里的虚拟内存分页管理方式把 KV Cache 分成固定大小的物理块按需分配从而显著减少了碎片浪费支撑更大的 batch 和更长的序列。实测下来同样的显存和模型vLLM 的吞吐可以比传统 Transformers 推理高出好几倍。llama.cpp 则更适合“单机搞定一切”的玩家。它直接把模型量化成 GGUF 格式支持纯 CPU 推理也能加载到 GPU 上加速部署成本极低。我有一次在只有 8GB 显存的笔记本上跑 7B 模型的量化版本配合 llama.cpp 也能获得每秒 5-8 token 的生成速度这在应急演示和本地开发场景下完全够用。TensorRT-LLM 适合那些对延迟极度敏感的线上业务它会对模型做深度图优化、算子融合、自动调优能把单次请求的延迟压到很低。但入门门槛也是几个方案里最高的编译优化过程动不动要几张 A100调优时间以天计。如果业务没有到毫秒级延迟竞赛的程度我建议不要一上来就选它。Ollama 更适合“不想折腾的人”。一条命令就能拉起 Qwen、Llama 等模型的服务内置了量化转换、API 接口管理。当然它也继承了便捷带来的种种限制如果你的请求模式非常特殊、需要自己写采样器、或者要深度控制显存调度Ollama 就不够灵活了。它更适合做原型验证和个人工具而非大规模生产基础设施。4.4 vLLM 部署服务的一线实操记录举个具体的例子。我最近把一个用 LoRA 微调过的 Qwen2.5-7B 模型部署成了生产 API 服务模型文件合并好之后导出为 HuggingFace 格式然后用 vLLM 启动服务。配置文件大概长这样model: ./merged_model tokenizer: ./merged_model max_model_len: 8192 gpu_memory_utilization: 0.90 dtype: float16 quantization: null启动命令简单但坑不少python -m vllm.entrypoints.openai.api_server \ --model ./merged_model \ --tokenizer ./merged_model \ --tensor-parallel-size 1 \ --max-model-len 8192 \ --gpu-memory-utilization 0.90 \ --dtype float16 \ --port 8000启动后如果遇到显存紧张可以把gpu_memory_utilization从 0.90 往下调比如调到 0.75给后续的 KV Cache 预留空间。还有一个我踩过的坑默认max-model-len是 2048如果客户端请求的上下文超过这个长度会直接报错或者被截断。所以如果要长期处理长文档一定要在启动参数里显式调大但代价是 KV Cache 会被更多预占并发量下降。服务起来后我用 Python 的openai库做了简单的压测同时并发打 20 个请求每个请求要求输出 512 token整体吞吐在 200-400 token/s 之间延迟在 2-4 秒。这个表现在业务上完全可以接受。如果要进一步优化就可以考虑量化 更细粒度的调度策略了。4.5 从 vLLM 扩展到多副本与负载均衡当单个 vLLM 实例撑不住更高级别的并发时就得考虑横向扩展了。最基础的方案是把服务拆成多副本每个副本独立启动一个 vLLM 服务再用 Nginx 或 Traefik 做负载均衡。实际操作中我会为每个副本指定不同的 GPU 和端口然后在 Nginx 里配置upstream指向这些实例。请求会按轮询或最少连接数算法分发到各个副本上。这样做的收益是并发能力随副本数量近似线性增长但要注意模型权重在每张卡上都要加载一份显存总量开销会成倍上升。如果有多卡服务器且单卡就能装下模型这个方案性价比很高。还有一个更省显存的方案是做张量并行--tensor-parallel-size 2把模型切到两张卡上单请求的延迟会降低但并发能力不一定有明显提升因为两张卡需要频繁通信同步。对于 7B 模型这种参数量级我试验下来感受是张量并行主要利好长序列、大批次的吞吐场景短请求多并发的场景下数据并行多副本收益更直接。5. 典型问题与排查心得这些坑我都替你踩过了5.1 微调后模型开始说胡话先查数据集质量和训练超参数这可能是微调阶段最常见的翻车现场花了几天时间训完模型回答开始偏离主题、出现重复文本甚至直接输出无意义内容。我碰到这种情况第一反应是检查训练数据的文本质量和覆盖度。如果数据集里存在较多重复、模板化或者彼此矛盾的样本模型很容易学到坏习惯。比如你准备了 5000 条“请把下面内容翻译成英文”的样本但里面有一半样本的答案其实就是输入原文那模型大概率会学到“抄原文”而不是“翻译”。数据清洗这一步绝对省不得至少要做去重、格式规整、标签一致性校验。排除了数据问题之后再回头看训练超参数。微调学习率太高是常见元凶。全量微调一般建议 1e-5 到 2e-5LoRA 可以适当放宽到 5e-5 到 2e-4但超过这个范围后模型泛化能力很容易崩。此外max length 太小会截断长文本样本导致模型学不到完整上下文batch size 太大也容易过拟合到少量模式上。我通常的做法是先用小数据集跑 1 个 epoch 做冒烟测试观察输出质量再正式上全量数据。5.2 推理服务显示 OOMcheck KV Cache 和显存预留策略推理服务 OOM 的频率比我预想的高不少。一个容易忽略的事实是vLLM 启动时就会为 KV Cache 预分配指定比例的显存这个比例由gpu_memory_utilization控制默认值是 0.90。如果你同时加载了量化权重或需要大量上下文这个 0.90 可能不够用。遇到 OOM建议思路先把gpu_memory_utilization调低到 0.70-0.75 试试然后检查是不是max-model-len设得过大导致 KV Cache 预占过多最后再确认 batch size 或并发策略是否需要调低。如果问题只在高峰时段出现那很可能要加副本或换更大显存的卡单纯调参数只能缓解不能根治。5.3 多模型共享显存部署的正确姿势不少团队使用多个微调模型比如按领域拆成法律、医疗、金融三个模型如果每个模型各自部署一套完整服务显存是巨大的浪费。LoRA 的模块化优势在这里非常明显同一个基座模型加载一次到显存多个 LoRA 适配器按需加载和切换就能服务所有领域任务。实际生产里vLLM 提供了 LoRA 的动态加载支持可以通过服务 API 动态指定使用哪个 LoRA 适配器还有一些团队用自定义 Router 层来做模型分派按请求的领域关键词或语义相似度路由到对应的 LoRA 上。我自己的项目里就是用这种方式在单张 A100 上同时服务了 3 个不同的 LoRA 微调模型显存占用比单独部署 3 个完整 7B 模型少了将近 60%效果却几乎没有损失。5.4 一个 Lambda 函数级别的排查清单排查过程中我会反复用一条简洁的检查清单来定位问题也分享给你备用模型能加载吗——检查路径、权限、依赖库版本单次请求能跑通吗——排除服务框架和路由问题并发一高就出错——大概率是显存或 KV Cache 不足特定输入出错——检查 tokenizer 和 max length 设置输出质量差——回到数据质量和超参数本身这套清单虽然简单但足够覆盖绝大多数灰度发布和线上事故场景。每次排查完我都会把结论记到项目的 Wiki 里后续再遇到类似问题直接查表效率提升非常明显。6. 一些在不同场景下验证过的选型参考说了这么多理论和方法最后给一张我做选型时的速查表你可以直接拿来当参考。我们先看训练和微调场景场景显存规模推荐方案备注个人 Laptop 跑 7B LoRA12GB-16GBQLoRA LoRA rank8先用小步长和学习率做验证单卡 A100 跑 13B LoRA40GB-80GBLoRA rank16效果和性价比都很好多卡 A100 跑 7B 全量微调4x80GBZeRO Stage 2/3 全量微调重点做数据质量验证控制学习率多卡集群跑 13B-70B 全量微调8x80GB 以上Megatron TP/PP/DP 混合并行非必要不建议尝试再来看推理场景的选型场景推荐框架核心配置本地单机、追求简单Ollama 或 llama.cppGGUF 量化4bit 起步生产 API 服务、高并发短对话vLLMAWQ/GPTQ 量化max-model-len按业务设定对延迟极敏感的业务TensorRT-LLM深度编译优化时间成本高多 LoRA 多领域复用vLLM LoRA 动态切换单基座模型 多适配器这些配置是我在多个真实项目里反复验证过的不敢说适用于所有团队但至少能帮你免掉一轮两眼一抹黑的踩坑。选型时最重要的原则有两条先明确自己的瓶颈到底是显存、吞吐还是延迟然后再去匹配框架和量化方案。不要一上来就追最前沿的工具那是资源无限充沛的大厂的玩法。7. 结语我的建议与个人体会大模型工程这条路走到现在我的一个核心体会是训练、微调、推理并不是三个孤立的阶段它们是一套需要整体设计的技术栈。训练阶段的数据配比影响模型微调的天花板微调时的超参数和 LoRA rank 又直接决定推理阶段需要多大的显存和选择什么样的部署方案。只盯着一环很容易在下一环被迫推倒重来。如果你现在正准备启动一个大模型项目我建议按这个顺序做决策先明确任务和指标——你要的是高吞吐对话、低延迟分类、还是长文档分析然后根据指标倒推模型规模和微调方案最终再根据显存和并发预期选择推理框架。每一步之间记得留出验证节点不要等问题堆到上线前才一起爆发。我还想再强调一次数据质量的重要性。很多微调效果不理想根子不在模型和框架而是在数据。把数据清洗、去重、格式对齐做扎实了用 LoRA 也能跑出媲美全量微调的效果。算力资源稀缺的团队更应该在数据层面多花时间这是性价比最高的投资。最后留一个后续可以深入的方向如果你要在生产环境大规模落地多模型服务可以进一步研究适配器融合把多个 LoRA 合并为单个权重文件、动态批处理和抢占式调度这些高级话题。大模型工程还很年轻每一个环节都有大量可以优化的空间但底层的“理解任务-设计数据-选择训练推理策略”这个框架短时间内不会变。