news 2026/10/9 5:44:51

DeepSeek全流程实操:分层预训练、LoRA微调与量化部署指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepSeek全流程实操:分层预训练、LoRA微调与量化部署指南

简介:一份面向算法工程师、AI研究者与深度学习初学者的DeepSeek全流程实操指南,系统讲解分层预训练、参数高效融合微调与蒸馏模型低比特量化,帮助读者从模型架构理解到训练推理落地建立完整认知。资源为单个PDF文件,共231页,大小约11.62MB,文档支持目录跳转和书签大纲快速定位,目前已有335人学习。全书共50个大章节,内容覆盖DeepSeek技术生态、数据筛选清洗与预处理、算力规划、超参数调优、掩码策略、梯度累积与混合精度训练、检查点管理与断点续训、损失函数设计、监控体系,以及数据标注规范、多模态标注、分布式训练、过拟合抑制、动态采样、学习率调度与硬件性能优化等,均有实操级讲解。适合需要系统掌握DeepSeek预训练与微调量化落地细节的读者,作为案头手册按章节查阅。

1. DeepSeek全流程实操:一份231页PDF背后的三层工程链路

如果你手头只有一张 24GB 显存的卡,却想让 DeepSeek 在你们团队的业务数据上真正能用起来,光“把权重跑起来”这一步根本不够。开源权重下载下来能用,和模型输出能解决业务问题,是两回事。把 DeepSeek 从入门练到精通,中间横着的其实是三段链路:分层预训练做领域适配、Parameter-Efficient 融合微调把行为对齐到业务、蒸馏模型加低比特量化把推理成本压回单卡能扛的范围。

这份标题里所谓 231 页的全流程指南,说穿了就是把这三段链路从头到尾梳理了一遍。它适合已经具备深度学习基础、想自己从零拉起一套 DeepSeek 服务的算法工程师或平台工程师,而不是只想知道怎么调 API 的业务同学。你可以照着这条链路做下来:先解决模型“懂不懂你的数据”,再解决“听话不听话”,最后解决“跑不跑得起”。这三关每关都有明确的参数、命令和坑,下面按顺序展开。

2. 分层预训练:先想清楚“冻结哪几层”再动手

2.1 分层预训练的基本盘:不是所有层都值得被更新

拿到 DeepSeek 这样的开源基座,目标一般不是从 tokenizer 开始重新练,而是让模型把行业语料里的表达方式、专有名词和长尾知识“补进”自己的参数。最忌讳的就是“一上来就全量训”。全量微调一开,推理能力和多轮对话习惯会被灾难性遗忘搅得七零八落,训练成本还特别高。分层预训练的思路是:把 Transformer 的几十层按阶段分组,低层负责词法、句法等通用能力,冻结或给极低学习率;高层贴近输出分布与任务语义,重点更新。这样领域知识的注入集中发生在上层,模型底子不会退步。

从模型结构角度,DeepSeek 跟 Llama/Qwen 这类稠密模型不一样的地方在于它是 MoE,注意力和专家网络被拆开。如果你的冻结策略只按“层”来切,会漏掉一类关键参数:路由 gate。MoE 的每个专家处理什么数据,路由层说了算。做分层预训练时,通常不冻结 gate 层,或者给 gate 单独一个低学习率,让领域语料能重新分配专家。这块没有公开的通用标准,很多团队就是靠实验标定,相当玄学;但“低层冻结、高层更新、gate 单独给学习率”这个框架是稳定可行的。

我一般会把模型层切成三段:前 1/3 冻结,中间 1/3 用较小学习率微调,最后 1/3 放开训练。如果数据量少,中段也可以只解冻注意力层,专家层留着后面微调再动。这样做的另一个好处是显存占用:冻结层不需要保存梯度,在 DeepSpeed ZeRO-3 下能明显降低通信量,对单机多卡训练更友好。

2.2 基于 DeepSeek 的继续预训练最小脚本

下面这段代码是继续预训练的第一步:加载模型、按层号冻结、打印实际可训练参数占比。以公开的deepseek-ai/DeepSeek-V2-Lite这类小 MoE 版本做演示,思路完全一致。

from transformers import AutoModelForCausalLM, AutoTokenizer model_id = "deepseek-ai/DeepSeek-V2-Lite" model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype="auto") tokenizer = AutoTokenizer.from_pretrained(model_id) # 按层号做三段分组:先冻结前 66% 的层 total_layers = model.config.num_hidden_layers freeze_until = int(total_layers * 0.66) for name, param in model.named_parameters(): # 参数名形如 model.layers.5.self_attn.q_proj.weight try: layer_idx = int(name.split(".")[2]) except (ValueError, IndexError): # 不属于 transformer 层的参数(embedding、norm 等)默认参与训练 continue if layer_idx < freeze_until: param.requires_grad = False trainable = sum(p.numel() for p in model.parameters() if p.requires_grad) total = sum(p.numel() for p in model.parameters()) print(f"trainable params: {trainable / total:.1%}")

这段代码的核心是“按层号冻结”:先通过config.num_hidden_layers拿到总层数,再把前 66% 层的所有参数关掉梯度。name.split(".")[2]依赖 transformers 那一层的命名格式,所以外面套了try/except,命名换了也不会直接把训练跑崩。

一个容易忽略的事实:embedding 和 lm_head 不在任何model.layers下面,上面的代码不会误冻结它们。但注意,lm_head是最后输出层,继续预训练时一般保持可训练,否则领域词汇永远映射不到输出空间。冻结比例从 0.5 起步,数据多可以放到 0.75,数据少就老实一点,冻结多一些。

如果想把 gate 单独放进高学习率组,需要再加一个分组操作。下面这段是通用的按层位置拆分参数组的写法,可以直接放进 Trainer 的optimizer参数构造里:

from transformers import Trainer from torch.optim import AdamW group_low, group_mid, group_high = [], [], [] for name, param in model.named_parameters(): if not param.requires_grad: continue layer_idx = int(name.split(".")[2]) if name.split(".")[2].isdigit() else -1 if layer_idx < int(total_layers * 0.33): group_low.append(param) elif layer_idx < int(total_layers * 0.66): group_mid.append(param) else: group_high.append(param) optimizer = AdamW([ {"params": group_low, "lr": 1e-5}, {"params": group_mid, "lr": 3e-5}, {"params": group_high, "lr": 5e-5}, ], weight_decay=0.01) trainer = Trainer(model=model, optimizers=(optimizer, None), ...)

分组的意义在于:低层不是“完全不学”,而是让它学得非常慢,避免把通用语法冲掉;高层学习率拉高,让领域语义快速成型。MoE 里的 gate 层位置分散在各层,如果你用的是统一分组,还需要单独把含gate的参数学出来放到group_low,防止路由分布被推得过于极端,这是很多翻车现场的直接原因。

2.3 三个必调参数:冻结比例、数据配比、学习率分段

下表是继续预训练阶段我每次都会先定死的三个参数组合。它们之间是耦合的,单看某一个意义不大。

参数建议取值范围说明
冻结比例0.5 ~ 0.75冻结太多学不进去领域知识;太少会显著加剧遗忘
领域数据 : 通用数据3 : 1 ~ 1 : 1纯领域数据会把模型带偏,必须掺通用语料防遗忘
三段学习率低层 1e-5 / 中层 3e-5 / 高层 5e-5以 1e-5 为基线,MoE 模型整体比稠密模型更敏感

数据配比是这三者里最容易被忽视的。很多人以为继续预训练就是“拿领域数据一直喂”,结果训练完模型领域术语说得溜,数学题和常识问答全面崩盘。原因是通用语料被稀释。我一般会保持至少 30% 的通用数据,并且在每个 epoch 里打散混合,而不是先领域后通用。

学习率分段也不能拍脑袋。继续预训练的常态是 loss 曲线前期快速下降、后期平台期很长。如果你发现领域 loss 降了但验证集的通用任务掉点超过 5%,优先怀疑学习率太高而不是数据配比;这时把高段学习率从 5e-5 降到 3e-5,通常比重新调数据更快见效。warmup 建议拉长到总步数的 10%——预训练阶段的 promise 是“数据量越大,warmup 越要长”,这和微调阶段的习惯完全相反。

3. Parameter-Efficient 融合微调:LoRA 为主选型与融合策略

3.1 各家 PEFT 横向选型:QLoRA、IA3、P-Tuning 在这条链路里的位置

分层预训练解决的是“模型懂不懂你的数据”,接下来对齐业务行为,标准做法落到 PEFT(Parameter-Efficient Fine-Tuning)上。这里把常用方案按“是否适合 DeepSeek 这种 MoE 模型”排一下:

方案原理显存占用对 MoE 的适配度适用场景
LoRA在注意力和 FFN 上注入低秩旁路中高默认首选,可离线合并
QLoRA基座量化到 4bit 再插 LoRA低中单卡显存吃紧时
IA3只学缩放向量最低中数据量极小、快速试探
P-Tuning v2在输入侧加可学习前缀中低少样本分类任务,不适合生成

我一般直接选 LoRA,原因有两条:一是它训练完可以 merge 回基座,部署链路干净;二是 MoE 模型里专家网络本身是稀疏激活的,QLoRA 把基座压到 4bit 后,量化噪声和路由选择叠加在一起,结果很不稳定。QLoRA 不是不能用,而是你需要花费额外的精力去排查“到底是量化伤了模型,还是 LoRA 没学对”,这排查成本在工程上一文不值。

IA3 适合做 baseline,把多个任务各自训一个 IA3 adapter,用最少显存验证数据质量。但它容量太小,真正上线时撑不住复杂指令,我通常只在第一天探索阶段拿来跑通流程,后面直接切 LoRA。

3.2 用 LoRA 对 DeepSeek 做领域微调:代码级实操

LoRA 微调 DeepSeek 有一个跟 Llama 系完全不同的点:DeepSeek 用的是 MLA(Multi-head Latent Attention),Q/K/V 会被压缩到一个低维隐含向量里再展开,所以权重名不是标准的q_proj、k_proj、v_proj。如果照抄 Llama 的 target_modules,大概率训练时 loss 能降、验证集怎么都不涨。正确做法是先打印模型结构,看清你这版权重里的投影层到底叫什么:

model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype="auto") for name, _ in model.named_modules(): if any(key in name for key in ("proj", "gate", "experts")): print(name)

输出里你会看到q_a_proj、q_b_proj、kv_a_proj_with_mqa、kv_b_proj、o_proj这类名字——它们是 MLA 的投影投影层。把 target_modules 对准这些名字,LoRA 才真正作用在注意力路径上。下面是完整的最小微调脚本:

from peft import LoraConfig, get_peft_model, TaskType lora_config = LoraConfig( task_type=TaskType.CAUSAL_LM, r=64, lora_alpha=128, # 以你上一步打印出的实际命名为准,以下只是 MLA 常见形态 target_modules=["q_a_proj", "q_b_proj", "kv_a_proj_with_mqa", "kv_b_proj", "o_proj"], lora_dropout=0.05, ) lora_model = get_peft_model(model, lora_config) lora_model.print_trainable_parameters()

几个参数说明。

r=64是 LoRA 秩。DeepSeek 这类 MoE 模型的路由层对秩不敏感,但 MLA 的隐含维度本来就不高,秩太大会让旁路矩阵学到冗余噪声。经验和 r=32 ~ 64 之间收敛稳定,数据量少于 10 万条时不要上 128。lora_alpha=128与 r 的比例保持在 2:1 左右,这是 PEFT 社区用下来的稳定区间,等于直接初始化旁路时就把缩放因子放大两倍,收敛更快。

target_modules里没有包含gate和experts。微调阶段我不建议对 MoE 的专家网络注入 LoRA。原因是专家层本身是稀疏的,如果给每个专家都加一个 LoRA 旁路,训练时路由选择一变,某些专家长期不被激活,对应的 LoRA 矩阵就白训了。gate 层同理,保持冻结即可。

训练时数据格式用对话模板。DeepSeek 系模型一般都有自己官方对话格式,指令和回答之间不能随便用<bos>分隔。最稳的方式是用transformers自带 tokenizer 的apply_chat_template把消息列表转成训练文本,别手拼模板。这步错了模型不会崩,只是指令跟随能力一直很奇怪。

训练完成后,LoRA adapter 单独保存:

lora_model.save_pretrained("./lora_adapter_domain") tokenizer.save_pretrained("./lora_adapter_domain")

adapter 权重很小,一般几十 MB 到两百 MB 左右,方便后面融合。

3.3 多 LoRA 融合:并行 adapter 与离线合并两种路线

“融合”这个词在这份链路里有两层含义。如果你只是想让多个技能共存,比如一个能写代码、一个懂业务术语,可以用 vLLM 的动态 LoRA 加载,部署时不合并权重,按请求路由到不同 adapter;如果你希望所有能力都固化进同一份权重,方便后续做量化和分发,就需要离线合并。

vLLM 路线适合在线服务:

vllm serve ./base_model \ --enable-lora \ --lora-modules code=./lora_adapter_code domain=./lora_adapter_domain

请求里带lora_name参数就能切换。它的优点是 adapter 可以热更新,训练完一个新 adapter 直接挂上去,不用重启服务。缺点是每个请求都要动态计算 LoRA 分支,吞吐量会比合并后低一些。

离线合并路线我一般用两步走:先把每个 LoRA merge 回基座,得到全量权重,再用 mergekit 做模型融合:

# 先把 adapter 合并回基座 python scripts/merge_adapter.py \ --base deepseek-ai/DeepSeek-V2-Lite \ --adapter ./lora_adapter_domain \ --output ./model_after_lora_domain

第二步用 mergekit 合并两份同基座权重。配置文件长这样:

# merge.yaml slices: - model: ./model_after_lora_code - model: ./model_after_lora_domain merge_method: dare_linear base_model: deepseek-ai/DeepSeek-V2-Lite dense_method: magnitude_prune parameters: theta: 100.0
mergekit-yaml merge.yaml ./model_fused --copy-tokenizer

dare_linear的含义是:把两份权重里贡献小的参数直接置零,再对剩余参数做加权平均。它跟朴素平均的关键区别就在“置零”这一步,能避免两份权重在同一位点上互相拉扯导致模型输出退化。theta=100.0是裁剪阈值,设得越小裁剪越激进,模型能力保留越少,但冲突越小。先 100 起调,如果合并后模型出现复读或答非所问,把 theta 调到 150 到 200 区间重试。

需要留个心眼:多 LoRA 融合之后一定要回到业务评测集上重新跑一遍,别只看合并后 loss。融合操作的目的是减少部署开销,能力上限不会比分别加载高,能用就行。

4. 蒸馏模型与低比特量化:把跑得慢的大模型变成可上线的服务

4.1 知识蒸馏的设计:把 DeepSeek 当 teacher 的落地方案

PEFT 微调做完,模型的行为已经对齐业务,但如果你用的是 DeepSeek 的满血版,单卡推理依然吃力。知识蒸馏的目的不是“提升效果”,而是把大模型学到的能力迁移到一个更小、更快的骨干上。在这个场景里,teacher 是微调好的 DeepSeek,student 可以选择同架构小模型,也可以选 Qwen/Llama 系的小稠密模型,后者部署更省心。

蒸馏方案我优先推荐 response-based,也就是让 teacher 生成高质量回答,student 直接拟合这些回答。它比 logits 蒸馏省显存、好实现。原因在于:DeepSeek 的输出层词表很大,student 要对齐整个词表分布,batch 稍微大一点显存就爆;而直接拟合回答文本,只需要用标准交叉熵。

如果你确实要上 logits 蒸馏,核心是温度系数和软标签的 KL 散度。一个可以照抄的蒸馏损失函数写法如下:

import torch import torch.nn.functional as F def distillation_loss(student_logits, teacher_logits, labels, temp=4.0, hard_weight=0.8): # 软标签:teacher 的输出分布 soft_targets = F.softmax(teacher_logits.detach() / temp, dim=-1) soft_loss = F.kl_div( F.log_softmax(student_logits / temp, dim=-1), soft_targets, reduction="batchmean", ) * (temp ** 2) # 硬标签:真实回答的交叉熵 hard_loss = F.cross_entropy(student_logits, labels, ignore_index=-100) return hard_weight * hard_loss + (1 - hard_weight) * soft_loss

温度temp=4.0是把 teacher 输出“摊软”,让 student 学到 token 之间的相似性,而不是死记最优解。temp太低软标签退化成 one-hot,蒸馏失去意义;太高会把噪声也放进去,student 学得含糊。hard_weight 控制在 0.7 到 0.9 之间,蒸馏是辅助信号,硬标签才是主线。

蒸馏数据集的生成是关键,也是坑最多的地方。常见做法是把业务侧的 prompt 清洗后灌给 teacher,温度设 0.7,每个 prompt 回复一遍或两遍。生成完必须做质量过滤:太短的删掉、包含重复片段的删掉、明显答非所问的删掉。蒸馏训练里最怕 teacher 的幻觉被 student 当标准答案学进去,这一步没有捷径,只能抽样本人工抽检。

4.2 蒸馏后的 4bit 量化:GPTQ/AWQ 选型与代码

蒸馏出来的 student 模型依然有几十亿参数,fp16 推理在消费级显卡上显存吃紧。低比特量化这一步,目标是把权重压到 4bit。主流的两个方案是 GPTQ 和 AWQ,二者选谁,取决于你的部署推理框架和校准数据。

GPTQ 基于二阶误差补偿,对校准集的依赖比较强;AWQ 基于激活值统计选择保留重要通道,通常更稳。如果蒸馏后的 student 是标准稠密模型,我倾向于 AWQ;如果你要配合 vLLM 的生态,GPTQ 的兼容性更无脑。两个都跑一遍取效果好的,也是常见姿势。

用 AutoGPTQ 库做 INT4 量化的最小流程如下:

from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig from transformers import AutoTokenizer model_path = "./student_model_after_distill" quantize_config = BaseQuantizeConfig( bits=4, group_size=128, desc_act=True, ) tokenizer = AutoTokenizer.from_pretrained(model_path) model = AutoGPTQForCausalLM.from_pretrained(model_path, quantize_config=quantize_config) # 校准数据:用业务侧真实样本,200~500 条即可 calib_samples = [ "你们产品的退款流程是什么?", "如何配置内网 DNS 服务器?", # ... 尽量覆盖线上真实请求 ] encodings = tokenizer(calib_samples, return_tensors="pt", padding=True) model.quantize(encodings) model.save_quantized("./student_model_int4")

group_size=128表示每个 128 个权重共享一套缩放因子和零点。bits=4是权重位宽,desc_act=True开启按激活顺序重排通道,精度更好但推理稍微慢一点。这两个参数是精度和速度的平衡点,不建议动。

校准集怎么选,比量化方法本身更影响结果。如果你拿通用语料做校准,量完的模型在业务场景会非常飘,因为校准集覆盖不到线上长尾分布。我一般从蒸馏数据里直接随机抽 300 条作为校准集,不要额外构造。

量化完成后放到 vLLM 里拉起服务:

vllm serve ./student_model_int4 \ --quantization gptq \ --max-model-len 4096 \ --gpu-memory-utilization 0.9

vLLM 对 GPTQ 的支持很成熟,--quantization gptq指定量化方式即可。需要注意group_size必须和量化时一致,vLLM 对某些 group size 的 kernel 支持有限,128 是目前兼容面最广的选择。

4.3 量化不止权重:KV Cache 量化与混合部署

很多人做完 weight-only 量化,发现长上下文场景下显存还是涨得飞快。问题出在 KV Cache。DeepSeek 系模型的 MLA 已经把 KV 压过一轮,但蒸馏后的 student 如果不用 MLA,长上下文的 KV Cache 依然是显存大头。vLLM 支持 KV Cache 量化,可以在推理时把缓存压到 fp8,基本不影响生成质量:

vllm serve ./student_model_int4 \ --quantization gptq \ --kv-cache-dtype fp8 \ --max-model-len 8192

--kv-cache-dtype fp8是显存吃紧时的后悔药。如果你只跑到 4096 上下文,可以先不开,先把权重量化带来的收益吃透。

部署阶段的另一个实际选择是“混合部署”:把蒸馏模型作为日常服务,遇到超难样本再转发到未量化的 teacher。这个方案在工程上很常见,我也一直推荐。它等于用 10% 的流量换来 90% 的精度兜底,等于给量化留了后悔药。转发逻辑可以在应用层做,模型侧不用改任何东西。

低比特量化最容易被忽略的验证项是“量化前后的输出差异”。很多团队只盯 benchmark 分数,忽略真实用户在意的回答风格。量化后如果模型回答变短、应变少,不是显存问题,是量化噪声把生成分布的尾端压平了;这时优先调整校准集,其次调 group_size 到 64,而不是换更复杂的量化方法。

5. 避坑排查:全流程最容易翻车的 5 个环节

5.1 分层预训练后,领域指标涨了但通用能力全面下滑

现象:领域数据上的 loss 降得漂亮,但常规问答、数学推理掉点超过 5%,甚至出现答非所问。

原因:最常见的是领域数据 : 通用数据配比失衡,或者高层学习率太高把通用语义冲掉了。另一个隐藏场景是 gate 层跟着高学习率走,路由分布被单一领域语料带偏,专家选择失去多样性。

解决:先把领域数据占比降到 50% 以下,掺回通用语料;再把高层学习率从 5e-5 降到 3e-5。如果掉点依然明显,检查 gate 参数是否被单独设成了低学习率,把包含gate的权重拆出来单独放一组。配比和学习率两个参数必须同时调,不能只动一个。

5.2 LoRA 训练正常但验证集不涨,问题出在 target_modules

现象:loss 曲线正常下降,打印可训练参数也没问题,但验证集指标一直原地踏步。

原因:把 Llama 系的["q_proj", "k_proj", "v_proj", "o_proj"]直接搬过来用,而 DeepSeek 的 MLA 投影层命名不同。LoRA 挂在了不存在的权重名上,或者挂在了一部分非关键投影上,训练时根本没注入到实际推理路径。

解决:训练前先打印model.named_modules(),确认你手上这版权重的投影层真实名称,比如q_a_proj、kv_b_proj这类,再填 target_modules。如果已经训了一半,也不用重来——adapter 权重和基座是分开存的,改完配置重新训即可,基座不动。

5.3 多个 LoRA 合并后模型像“哑巴”,输出空洞重复

现象:合并后模型的输出变短、复读严重,或者不同任务的能力互相干扰。

原因:直接把两个 adapter 权重做算术平均,同一位点上两个任务的方向互斥,参数抵消。这个问题在模型容量越小的时候越明显,蒸馏 student 上几乎必现。

解决:采用 mergekit 的dare_linear或dare_ties方法,先按幅度裁剪再平均,避免参数冲突。theta从 100 起调,模型越小 theta 越大,比如 150 到 200。合并完必须过一轮业务评测集,不要只看困惑度。

5.4 蒸馏 student 量化后困惑度飙升,而不是小涨

现象:量化前困惑度 9.5,量化后直接跳到 15 甚至更高,生成质量肉眼可见地下降。

原因:蒸馏阶段温度设得太高或 hard_weight 太低,student 的输出概率分布过于平缓,量化时按激活统计保留重要通道的依据失真。换句话说,student 学到的分布“太软”,4bit 量化一压,噪声被放大。

解决:先看训练日志里的蒸馏损失构成,把 hard_weight 提到 0.9,温度降到 3 以下,重新蒸馏。如果时间不允许重训,就用 AWQ 替代 GPTQ,AWQ 对激活分布更鲁棒,通常能救回大半损失。同步检查校准集是否用了业务侧数据,通用语料校准在蒸馏模型上更容易翻车。

5.5 量化模型部署后显存依然超预期,服务被 OOM 打死

现象:4bit 权重加载后,用 vLLM 一跑长上下文,显存还是爆,多个并发直接 OOM。

原因:只量化了权重,没算 KV Cache。长上下文下缓存占用甚至超过权重本身;另外 vLLM 默认给每个请求预留最大上下文的 KV,并发高时显存成倍增长。

解决:先加--kv-cache-dtype fp8压缩缓存;再把--max-model-len从 8192 降到业务真实需要的长度,比如 4096;最后调低--gpu-memory-utilization到 0.85,给调度器留出换入换出的缓冲。如果还超,就要回到模型侧,换更小的 student 或更激进的量化组配置。

6. 收尾验证:上线前用一份体检清单确认整条链路真的成立

全流程跑完,最怕的是每个环节单独看都没问题,串起来却守不住业务。我的习惯是每次做完一版,都按下面这张表逐项过一遍再决定要不要上线。

检查项方法通过标准
基座语言能力困惑度 + 通用基准走 100 条抽测与量化前相比差距小于 5%
领域知识注入抽取 50 条领域问答,人工打分关键实体与术语准确率不低于 90%
指令跟随跑 30 条多轮指令,检查格式与拒答无复读、无跑题、无空回答
量化损益同一批 100 条 prompt 对比 int4 与 fp16 输出语义一致率大于 95%
显存与吞吐vLLM 压测 20 并发,观察显存峰值峰值低于显卡显存的 90%

评估这一步不要只看单项指标。常见误区是量化后用困惑度做唯一判断,但困惑度对量化噪声不敏感,可能显示“没变化”,实际生成风格已经变了。我一般会在业务侧准备一批真实用户请求,量化前后各跑一遍,用字符串编辑距离加人工抽样来评估输出一致性。

还有一个我吃了亏才养成的习惯:每完成一步,就把config.json、tokenizer 文件和 adapter/量化权重各存一份,文件名带步骤编号,绝不覆盖。分层预训练、PEFT 融合、蒸馏、量化,这四个状态分别对应一份可回溯的权重。你永远不知道下一步会不会把一个环节推翻重来,这些就是你的后悔药。

最后提醒一句:蒸馏和量化能解决成本问题,不能解决数据问题。如果业务效果本身不行,回到第 2 章和第 3 章检查数据配比和 LoRA 参数,别在最后两章里找原因。这条链路跑通一次之后,后面每换一个领域,真正要重做的只有数据整理和校准集,希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 5:44:11

采购方问的是意图,工厂信息得按意图组织

这篇是“生成式引擎可见性”笔记的第六篇。前五篇分别写了能不能被读到、能不能被摘走、旧话怎么换成新话、跨源能不能归到同一个“我”&#xff0c;解决的是同一层面的事——单份材料够不够格被机器读、被摘、被更新、被认出来。这篇补的是那几篇都绕过去的一层&#xff1a;采…

作者头像 李华
网站建设 2026/10/9 5:43:36

GitHub热榜日榜:从star增长到项目上手的完整筛选指南

GitHub 热榜项目&#xff1a;日榜&#xff08;2026-10-04&#xff09;GitHub 热榜项目&#xff1a;日榜&#xff08;2026-10-04&#xff09;——这个标题对常刷开源社区的人来说一点都不陌生。每天晚些时候&#xff0c;Trending 更新&#xff0c;当天的新项目、新工具、新话题都…

作者头像 李华
网站建设 2026/10/9 5:43:18

PS5串流实战:把主机变成Any设备都能玩的游戏平台

我家客厅的电视只有一块&#xff0c;PS5却长在它屁股后面拔不下来。周末想看会儿B站都得先让位&#xff0c;更不用说把主机搬到卧室、带回老家或者是出差时想刷两把。直到我把“AnyPS5”这套思路真正落地&#xff0c;才算是把客厅那台PS5从电视旁边彻底解放了出来——不管人在哪…

作者头像 李华
网站建设 2026/10/9 5:41:08

两份固件都叫 v1.4,怎样查清设备实际烧了哪一份?

同一个版本号&#xff0c;测试台上的板子能连上&#xff0c;现场那块却连不上。两边都说用的是“v1.4”&#xff0c;聊天记录里还有三份同名的 firmware.bin。这时再讨论谁的操作有问题&#xff0c;通常没有用&#xff0c;先要把设备、二进制和构建输入对应起来。 下面沿着一次…

作者头像 李华
网站建设 2026/10/9 5:40:57

《HTML + ECharts 打造外卖优惠数据可视化大屏》(附源码)

一、项目概述技术栈&#xff1a;可视化库&#xff1a;Apache ECharts 5.5&#xff08;CDN 引入&#xff09;页面骨架&#xff1a;原生 HTML CSS Grid Flexbox边框装饰&#xff1a;手写 CSS/SVG&#xff08;仿 DataV 边框盒&#xff0c;无需引入 DataV 依赖&#xff09;部署方…

作者头像 李华
网站建设 2026/10/9 5:40:56

企业AI Agent定制:条款指向附件,为何就查不到?

一份采购合同里写着&#xff0c;付款节点与违约责任详见附件三。员工向助手提问违约金的计算方式&#xff0c;得到的回答是资料中没有找到相关说明。打开合同原件可以看到&#xff0c;附件三确实随合同一并上传&#xff0c;内容里也写清了比例&#xff0c;只是助手没有把正文里…

作者头像 李华