
简介这是一份深度解读DeepSeek系列大模型技术的PDF资料面向AI算法工程师、大模型爱好者与关注开源模型发展的技术人群内容系统梳理V3、R1、Janus-Pro的核心创新帮助读者快速理解MoE混合专家架构、MLA潜注意力、无辅助损失负载均衡、节点限制路由、多Token预测、DualPipe跨节点通信以及FP8混合精度训练等关键机制。包体为1个PDF文件压缩包大小8.04MB便于直接阅读与保存。目前已有183人学习下载。资料结合DeepSeek-V3开源仓库与论文要点对比传统模型结构解释671B总参数仅激活37B参数背后的工程取舍并指出开源对闭源生态的挑战及中国AI追赶西方的最新进展。读者可借此掌握大模型高效训练的系统性思路尤其适合需要了解先进模型架构细节和工程优化方法的技术人员。1. 为什么把 DeepSeek V3、R1、Janus-Pro 放在一起看才算深度解读大模型技术深度解读 DeepSeek 大模型技术很少有人把 V3、R1、Janus-Pro 三份报告摊在同一张桌上。V3 讲的是规模与成本的矛盾671B 总参数怎么做到只要激活 37BR1 讲的是推理能力怎么从强化学习里长出来模型不靠人工标注也能学会长思考Janus-Pro 则把问题从纯文本挪到多模态告诉你为什么理解任务和生成任务不能共用同一个视觉表征。三份报告共享同一套语言模型底座但解决的分别是工程、训练、多模态三件事。如果你在考虑私有化部署先用第 2 章的显存估算和启动命令如果更关心奖励设计和模型蒸馏可以直接从第 3 章的 GRPO 对比读起。下面这条线是按“架构 → 强化学习 → 多模态 → 部署接入”推演的尽量让每段都能复现。2. DeepSeek V3MoE 架构与成本效率如何同时成立2.1 从 Dense 到 MoE为什么 671B 参数反而能省钱V3 最反直觉的地方是把总参数推到 671B实际每次前向只激活 37B。这个效果来自 MoE也就是把 Transformer 里的 FFN 层替换成一组并行专家 FFN再由路由网络每次挑选 top-k 个专家。对单个 token 来说计算量和约 37B 的 dense 模型接近但总参数让模型容量变大知识被分散到更多专家里。训练时每步算力变便宜收敛到同等 loss 的硬件成本更低这是 V3 能把大模型预训练成本压下来的核心原因。部署时要记住一个区别激活参数决定单 token 的推理算力总参数决定显存占用的下限。671B 权重即使压缩到 FP8 也接近 700GB单卡不可能直接装下。这也是为什么 V3 的落地几乎都走多卡张量并行或者 API本地个人设备更适合用后面提到的 R1 蒸馏小模型。2.2 MLA 与 DeepSeekMoE多头注意力和专家路由的工程取舍V3 的注意力用了 MLAMulti-head Latent Attention思路是把每个头的 K、V 先投影成一个低维潜在向量做注意力计算时再展开。这样对长上下文友好因为 KV cache 不再随序列长度按头数线性膨胀。实际训练时还需要 RoPE 对位置信息做旋转MLA 通过把 RoPE 单独放在一个低秩分支上来兼容这一套属于工程上很细的折中。专家侧沿用 DeepSeekMoE 的细粒度设计路由专家数量很大每个 token 激活少量专家同时保留一个共享专家必走保证公共知识不被路由错过。传统 MoE 需要加辅助损失来防止路由扎堆V3 换了个做法用一个不参与梯度更新的 bias 项记录每个专家的负载路由打分时加上这个 bias让使用率低的专家更容易被选中。这样既维持了专家均衡又不会因为辅助损失干扰主任务的梯度。V3 关键配置在 MoE 里的作用调整时的注意点n_routed_experts路由专家总数V3 技术报告里为 256增大只涨总参数量和显存不显著增加激活算力num_experts_per_tok每个 token 激活的专家数V3 为 8决定单 token 推理算力直接影响吞吐n_shared_experts共享专家数V3 为 1每个 token 必走适合放通用知识kv_lora_rankKV 低秩压缩维度调大提升注意力表达但 KV cache 占用上涨2.3 用 vLLM 启动 DeepSeek-V3 服务先看显存和并行度本地部署 V3 时我一般直接用 vLLM 起 OpenAI 兼容服务而不是自己写动态批处理。命令里最关键的是张量并行数要按 GPU 卡数和显存来定vllm serve deepseek-ai/DeepSeek-V3 \ --tensor-parallel-size 16 \ --max-model-len 8192 \ --gpu-memory-utilization 0.9 \ --dtype bfloat16 \ --served-model-name deepseek-v3--tensor-parallel-size 16表示把模型切到 16 张卡上并行跑显存不足时优先调大这个数--max-model-len 8192控制 KV cache 上限V3 本身支持更长的上下文但部署时拉得太高会挤占并发空间--gpu-memory-utilization 0.9让 vLLM 预占九成显存留一部分给调度和新分配的 cache block--dtype bfloat16比 FP8 更通用FP8 权重需要专门 kernel 支持。如果只有 8 张 80GB 显存的卡就把并行数改成 8并且确认权重是 FP8 或 BF16 规格。2.4 拉起权重后先做一次 MoE 配置自检很多部署事故不是显存算错而是拉错了权重。DeepSeek-V3 的 repo 里会带 config.json字段名能直接告诉你这份权重是不是标准 MoE 结构import json from pathlib import Path cfg json.loads(Path(config.json).read_text()) keys [n_routed_experts, num_experts_per_tok, n_shared_experts, kv_lora_rank] for k in keys: print(k, cfg.get(k))如果输出里n_routed_experts是 256、num_experts_per_tok是 8说明确实是 V3 的 MoE 结构如果这些字段不存在大概率是拉到了某个 dense 蒸馏版或非官方转换权重。这个检查和下载后校验 sha256 一样应该成为部署流程里的固定动作。3. DeepSeek R1把强化学习用在做题上奖励模型怎么设计3.1 R1-Zero 到 R1冷启动、拒绝采样、两阶段强化学习R1-Zero 是 R1 的前置实验不喂任何 SFT 推理样例直接用强化学习在数学、代码这类可验证任务上训练。模型自己发展出了重新审题、反思步骤、验证结果这些行为说明推理链不一定需要人类示范结果奖励足够强就能涌现。但副作用也很明显输出夹杂中英文、可读性差、格式混乱。R1 的改进是先把冷启动 SFT 数据加进流程让模型学会用统一标签把思考过程和最终答案分开再跑两轮强化学习。第二轮强化学习还有一个关键操作先用第一轮 RL 模型采样大量结果再做拒绝采样选出答案正确或者奖励分高的样本作为下一轮 SFT 数据。这是一个典型的“RL 生成数据 → SFT 模仿 → 再 RL”循环比直接一次性 RL 更稳。设计自己的 RL 流程时可以直接照搬这个节奏冷启动数据不需要太多但覆盖的 prompt 分布必须和最终任务一致。3.2 GRPO 为什么比 PPO 更适合大模型 RLR1 训练用的强化学习算法是 GRPOGroup Relative Policy Optimization。PPO 需要同时训练一个价值网络来估计状态价值再算 GAE 优势GRPO 不训练价值网络而是对同一个 prompt 采样一组输出用这组输出内部得分的均值、标准差做 z-score 归一化作为每条样本的优势值。省掉价值网络之后显存占用小一截训练管线也简单很多。对比项PPOGRPO价值网络需要不需要优势计算GAE critic 预测组内 (r_i - mean) / std训练显存多一路 critic 参数和优化器状态少一路更省显存适用场景通用 RLHF奖励函数多样数学、代码等可批量评分的任务用 GRPO 时组内样本数 k 直接影响优势估计质量。k 太小均值容易抖动k 太大采样成本线性上涨。常见做法是 k 取 4 到 8在评测集上对比一组结果后再确定。3.3 可复现的奖励配置答案验证 格式检查R1 报告里把奖励分成两类可验证奖励和格式奖励。可验证奖励不依赖训练好的 reward model直接判断最终答案是否正确格式奖励则是检查输出是否以reasoning开头、是否包含answer标签。我一般会把这两件事拆成独立函数方便在 RL 训练里分配不同权重。import re def extract_answer(text: str) - str: m re.search(r\\boxed\{([^}]*)\}, text) if m: return m.group(1).strip() return re.sub(r\s, , text) def answer_reward(pred: str, gold: str) - float: return 1.0 if extract_answer(pred) re.sub(r\s, , gold) else 0.0 def format_reward(text: str) - float: if text.startswith(reasoning) and answer in text: return 1.0 return 0.0extract_answer优先从\boxed{}里抽结果抽不到就把空白全部去掉再做字面比较这样能兼容 LaTeX 答案和普通文本答案。answer_reward给的是硬性对错信号format_reward给的是稀疏的结构信号。实际训练里可以给格式奖励低权重避免模型为了格式正确而忽略答案内容。3.4 把 R1 蒸馏到 7B 做本地推理一个最少调用片段R1 报告里有一条很实用的分支把自己生成的 80 万条数据拿去微调小模型蒸馏出 1.5B 到 70B 的系列。本地个人电脑最合适的往往是 7B 蒸馏版它保留了一部分长思考格式但显存需求降到个位数 GB。加载方式和一个普通 Qwen 模型差别不大from transformers import AutoModelForCausalLM, AutoTokenizer import torch model_name deepseek-ai/DeepSeek-R1-Distill-Qwen-7B tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained( model_name, torch_dtypetorch.float16, device_mapauto ) messages [{role: user, content: 一个三角形三边分别为3、4、5求面积。}] text tokenizer.apply_chat_template(messages, tokenizeFalse, add_generation_promptTrue) inputs tokenizer(text, return_tensorspt).to(model.device) output model.generate(**inputs, max_new_tokens1024, do_sampleFalse) print(tokenizer.decode(output[0][inputs.input_ids.shape[1]:], skip_special_tokensTrue))max_new_tokens一定要给足蒸馏模型也会先写很长一段思考过程截断后经常只剩半句话没有最终答案。do_sampleFalse适合做评测日常使用可以改成do_sampleTrue配合temperature0.6、top_p0.95这个参数组合在 R1 系列里比较通用。4. Janus-Pro统一理解与生成时为什么要把表征拆开4.1 一个多模态编码器同时做两件事的代价Janus-Pro 要解决的是多模态大模型里一个经典矛盾理解任务和生成任务对视觉表征的要求不同。做图片理解时模型需要的是高层语义比如这张图里有什么、物体之间的关系做文生图或图像补全时模型又需要像素级的空间细节和颜色纹理否则生成的图会糊。如果把两种目标压进同一个视觉编码器训练信号会互相牵扯。早期很多模型选择理解优先生成能力就弱反过来生成优先理解任务的精度又会往下掉。Janus-Pro 给出的解法不是换更大的 encoder而是把两条路径在表征层分开只在语言模型主干里汇合。4.2 解耦后的两条路径SigLIP 接理解独立视觉 tokenizer 接生成Janus-Pro 的架构里理解侧用 SigLIP 这样的视觉编码器提取特征经过投影层转成 LLM 能读的向量生成侧用另一套独立的视觉 tokenizer 和图像解码器把图像变成离散 token 序列再交给 LLM 做自回归生成。两条路径各自的视觉特征不会在中间共享避免了表征空间污染。这个设计对做多模态研发的人很有参考价值。它不是“再加一个 adapter”那么简单而是从一开始就承认理解特征和生成特征是两种东西。工程上的代价是权重多了一套视觉编码器推理时也要根据任务是理解还是生成走不同分支换来的则是两边都可以单独调参和升级不会因为改进生成效果而毁掉理解效果。4.3 用 transformers 跑 Janus-Pro最小文本推理与图像输入入口Janus-Pro 的模型权重会放到 Hugging Face 上因为代码不在 transformers 主仓库里加载时一般需要开trust_remote_code。先看文本分支的完整调用from transformers import AutoModelForCausalLM, AutoTokenizer import torch model_name deepseek-ai/Janus-Pro-7B model AutoModelForCausalLM.from_pretrained( model_name, trust_remote_codeTrue, torch_dtypetorch.bfloat16, device_mapauto ) tokenizer AutoTokenizer.from_pretrained(model_name, trust_remote_codeTrue) prompt 请用一句话描述这张图片里最显眼的颜色。 inputs tokenizer(prompt, return_tensorspt).to(model.device) out model.generate(**inputs, max_new_tokens256, temperature0.7, top_p0.95) print(tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokensTrue))真正传入图片时需要走官方仓库里的VLChatProcessor它会负责把图像预处理成理解侧需要的像素张量或者生成侧需要的离散图像 token。常见做法是先构建好一个多轮 conversation再调用 processor 统一编码from janus.models import VLChatProcessor processor VLChatProcessor.from_pretrained(deepseek-ai/Janus-Pro-7B) conversation [{role: |User|, content: 描述这张照片的光线。}, {role: |Assistant|, content: }] inputs processor(conversationconversation, images[pil_image], force_batchifyTrue).to(model.device)force_batchifyTrue会把单张图片变成带 batch 维的输入之后直接把inputs传给model.generate。如果返回结果里没有图像相关输出优先检查传入的图片尺寸是否在预训练分辨率附近Janus-Pro 对过小的缩略图表现会明显下降。4.4 图像生成时必调的采样参数参数控制内容调参建议temperaturetoken 采样随机性文本对话取 0.7图像生成过高会出乱码top_p核采样保留概率0.9 到 0.95越低输出越保守img_gen_cfg_weight生成图像时的 classifier-free guidance 权重纯文本对话不用动图像生成按效果从 1 到 7 网格搜索img_gen_cfg_weight是 Janus-Pro 生成图像特有的参数它控制模型在“有图条件”和“无条件”之间的偏向程度。权重太低图像细节会往平均值糊太高又容易出现伪影。我一般先固定 temperature 和 top_p只调这一个权重观察边界效果后再回去微调另外两个。5. 本地部署 DeepSeek 的最小可行步骤与三个坑5.1 一条命令把 R1 蒸馏版变成 OpenAI 兼容接口如果你想在本地把 DeepSeek 蒸馏模型接进自己的工具链最省事的方式是用 vLLM 起一个 OpenAI 兼容服务而不是写自定义推理 HTTP 服务vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-7B \ --served-model-name r1-7b \ --max-model-len 8192 \ --port 8000启动后默认在/v1路径暴露接口模型名是r1-7b。--max-model-len决定单条请求能占用的最大上下文8K 是个人设备比较平衡的起点。5.2 用 Codex CLI、VSCode 和 CC Switch 接 DeepSeek API工具接入的关键是先确认目标工具支持 OpenAI 兼容base_url。Codex CLI 可以通过环境变量指定本地服务地址VSCode 里的 Cline、Continue 也大多在设置页填 Api Base URL 就能切换CC Switch 这类桌面切换工具同样只是把 base_url、api key 转发给上层应用。export OPENAI_BASE_URLhttp://localhost:8000/v1 export OPENAI_API_KEYEMPTY codexapi_key填EMPTY即可因为本地 vLLM 不做真实鉴权。注意先启动 5.1 的服务再开这些前端否则连接池会直接报 refused。5.3 三个高频翻车点第一个是max_tokens。R1 蒸馏版会把推理过程写在生成文本里很多工具默认只给 256 或 512结果就是回答停在“让我想想”半路。第二个是temperature。DeepSeek 官方 API 的 reasoner 模型不建议额外设置温度本地 vLLM 跑蒸馏版时用 0.6 左右比较合理别拿普通 chat 的 0.3 套过去低温度会让长思考重复。第三个是max-model-len。为了省显存把上下文拉到 32K 看起来高级但 KV cache 会吃掉大量显存导致并发吞吐直线下降建议先跑一轮压测再加长度。5.4 用一道数学题做回归验证接入完成后我会用一道结果唯一的数学题验证链路是否端到端可用同时检查格式标签有没有被保留from openai import OpenAI client OpenAI(base_urlhttp://localhost:8000/v1, api_keyEMPTY) resp client.chat.completions.create( modelr1-7b, messages[{role: user, content: 7×8等于多少请用reasoning和answer标签输出。}], max_tokens1024, temperature0.6, ) content resp.choices[0].message.content assert answer56/answer in content, content print(deepseek api 本地链路正常)content里同时包含推理过程和最终答案只断言答案标签能避免把接口连通性和推理质量混在一起。如果这道题输出是空或挂掉了再回头查 vLLM 日志和模型加载路径只要这道题通过接 Codex、VSCode 或任何 OpenAI 兼容工具都不会有方向性问题。本文还有配套的精品资源点击获取