大模型推理架构与开源生态知识整理

大模型推理全流程与开源架构知识库

本手册整理自大模型底层处理机制、分词原理、MoE 架构及开源生态的深度探讨,旨在建立一个从用户请求到模型输出的完整认知链路。


一、 大模型推理全流程解读(从 API 输入到最终输出)

这是大模型"处理请求"的完整生命周期。我们可以把它拆解为 8 个核心步骤

第 1 步:API 请求接收与预处理

  • 动作 :用户通过 HTTP 接口发送请求。请求体通常是 JSON 格式,包含多轮对话列表(例如 {"messages": [{"role": "user", "content": "你好"}]})以及推理参数(temperaturetop_p 等)。
  • 底层:推理服务网关收到请求后,进行权限校验和负载均衡。

第 2 步:角色提示词格式化(应用 Chat Template)

  • 动作 :服务端调用分词器(Tokenizer)的 apply_chat_template 方法。将传入的 [{"role":"user", "content":"你好"}] 对话列表,根据 tokenizer_config.json 里的 Jinja2 模板 ,拼装成一段连贯的单一字符串
  • 示例结果 :原始 JSON 被转换为类似 <|im_start|>user\n你好<|im_end|>\n<|im_start|>assistant\n 的格式。

第 3 步:字节对编码(BPE)与词表查表

  • 动作 :对拼装好的字符串进行子词切分,并对照词表(Vocabulary)映射为整数(Token ID)
  • 细节
    • 包含特殊符号添加:根据配置里的 add_bos_token,在开头强制插入开始标记(如 <|begin_of_text|>)。
    • 采用贪心最长匹配策略,尽可能合并为词表中已有的长子词。

第 4 步:序列长度处理(截断与填充)

  • 动作 :判断生成的 Token ID 数组长度是否超过 model_max_length。如果超过,则按配置的 truncation_side 进行截断。
  • 批量填充 :如果服务端将多个用户的请求合并成一个 Batch(批次),为了形成规整的矩阵,短句必须补全。根据 padding_side(通常为 left),在左侧使用 pad_token_id 将长度补齐。

第 5 步:张量转换与硬件部署

  • 动作 :将整型数组(例如 [1, 3001, 456, ...])转换为 PyTorch 或 TensorFlow 的 Tensor 张量,并通过 CUDA 等接口放入 GPU 显存中。

第 6 步:神经网络核心推理(与 MoE 激活)

  • 动作:GPU 开始执行 Transformer 层的前向传播。
  • Dense(稠密)模型:每层计算包括注意力机制(Attention)和前馈网络(MLP)。
  • MoE(混合专家)模型(重要区别)
    • 在特定层遇到 mlp.router(门控网络),门控计算出每个 Token 应该分配给哪个专家。
    • 系统只激活 配置中的 Top-K 个专家子网络进行计算(例如 Top-2),其余专家不参与算力消耗,但权重依然占满显存
    • 输出加权合并结果。
  • 计算结果 :模型最终输出一个概率向量(Logits),表示下一个最可能出现的 Token ID 的分数。

第 7 步:自回归生成与反向查表解码

  • 动作 :根据 generation_config.json 中的策略(如 temperature 采样或贪心搜索),从 Logits 中选出一个具体的整数 Token ID。
  • 反向查找 :系统拿着这个整数 ID,再次对照词表进行反向查表,将这个 ID 映射回人类可读的文字。
  • 循环:将生成的文字拼接到上文的 Token 序列尾部,再送回模型推理(重复步骤 3-6),直到模型生成结束符(EOS Token)或达到最大输出长度。

第 8 步:API 响应返回

  • 动作:服务端将累积生成的文本封装成 JSON 格式,或通过 SSE(Server-Sent Events)流式传送给用户,完成一次完整的交互。

二、 核心深度知识:分词器与"查表"的玄机

1. BPE(字节对编码)是如何"学会"切分的?

  • 训练阶段(生成词表) :先在语料中统计高频相邻字符对,将它们合并为子词。反复迭代直到达到预设的词表大小(如 Llama 3 的 128k)。最终生成 vocab.json(词表映射)和 merges.txt(合并规则)。
  • 推理阶段(实际切分)不重新生成规则,只是拿着已有的词表,采用"贪心最长匹配"原则将输入文本切成子词。
  • 切分为子词的优势:解决了传统"整词切分"词表过大、处理生僻字会报错(OOV)的缺陷,同时比"单字切分"能保留更强的语义信息。

2. 为什么"数字计算"中间不查表?

  • 输入 :Toke ID → Embedding 矩阵 → 浮点数向量。
  • 中间:纯线性代数和微积分运算(查询不参与计算)。
  • 输出 :Logits → 反向查表 → 输出文字。

三、 分词器的专有性(不同模型不可通用)

结论 :BPE 算法是共用的(造字典的方法),但词表和训练规则是每个模型独有的财产。只要词典不一样,Llama 的分词器就不能拿去处理 Qwen 的模型。

  • 原因 1 :词表大小和词袋侧重不同。例如 Llama 的英文词表极细致,但遇到中文"人工智能"会被切成 4 个单字;而 Qwen 的中文词表里它是一个完整的 Token。
  • 原因 2 :控制符(Special Tokens)不同。Llama 用 <|start_header_id|>,Qwen 用 <|im_start|>。混用会导致模型找不到控制符 ID 而崩溃。
  • 工程铁律tokenizer_config.jsonvocab.json 和模型权重文件(.safetensors)必须来自同一个 Hugging Face 仓库的同一个版本,绝对不能交叉混用。

四、 开源大模型仓库内容全解(标准版 + MoE 架构进阶)

一个完整可用的开源大模型仓库(如 Hugging Face)会包含以下五大类。注意:MoE 架构的仓库,其特有组件内嵌于这些文件之中,而非独立外挂!

1. 模型权重文件("大脑")

  • 标准模型.safetensors.bin 格式,因体积巨大被切分成 model-00001-of-xxxxx.safetensors,并伴随 model.safetensors.index.json 索引文件。
  • MoE 模型内部差异 :在这些权重分片的张量名称里,你可以看到 mlp.router(门控网络)和 mlp.experts.0.up_projmlp.experts.7.up_proj(多个专家的小模型矩阵)。它们的权重必须全部加载到显存中,但在推理时由门控决定只激活少部分专家参与计算。

2. 配置文件("骨架"与"出厂设置")

  • config.json(核心骨架) :定义了层数(num_hidden_layers)、维度、激活函数。如果是 MoE 模型,还会增加 num_local_experts(专家总数)、num_experts_per_tok(每个 Token 激活几个专家)。
  • generation_config.json(输出策略) :定义了默认的 max_lengthtemperaturetop_p 和重复惩罚参数。

3. 分词器文件("翻译官"与"字典")

  • tokenizer_config.json:定义加不加 BOS、填充位置、聊天模板(Jinja2)等。
  • vocab.json / merges.txt :BPE 的对照表和合并规则(或 tokenizer.model 二进制文件)。

4. 模型运行代码("心脏起搏器")

  • modeling_*.py / configuration_*.py:定义了 Transformer 和 MoE 前向传播的 PyTorch 底层实现逻辑。

5. 说明文档与法律授权("身份证")

  • README.md:模型能力、显存要求、局限性。
  • LICENSE:商用授权的关键。Apache 2.0、MIT 可自由商用;Llama 系列有特定的月活用户限制。

五、 工程实践指南(避坑与诀窍)

  1. 不要手动拼装 :如果你使用 transformers 库,务必直接调用 tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=True)。框架会自动读取 tokenizer_config.json 里的模板,一步完成前 4 步,防止自己手写逻辑出错。
  2. MoE 工程风险警示 :MoE 模型因为全量专家都常驻显存,显存占用极为恐怖;并且推理框架(如 vLLM、DeepSpeed)需要专门的 MoE 通信调度代码,部署前必须确认推理引擎是否适配。
  3. 量化策略差异 :在对 MoE 模型进行量化(GGUF/GPTQ)时,门控网络(Router)必须保留高精度(通常不量化)。因为门控算错一个数导致选错了专家,模型的输出会产生灾难性崩坏。专家参数则可以放心量化压缩。
  4. 扩展词表与微调 :如果你想把一个纯英文模型(如 Llama)补全中文能力,必须在微调之前重新训练该模型的分词器 ,并重新初始化 Embedding 层权重,这意味着你必须消耗资源进行额外的"部分预训练",而不是简单的 LoRA 微调就能完成。
相关推荐
Marst Code4 小时前
(python)2026Plotly 库评估:交互式可视化到底值不值得引入?
开发语言·python
databook4 小时前
当散点图不够用时:用 t-SNE 可视化多维数据
python·数据分析·数据可视化
字节跳动开源4 小时前
30 分钟搞定个人情报站:Viking AI 搜索让前沿资讯实时推到面前
数据挖掘·开源·agent
爬也要爬着前进5 小时前
redis主从搭建
数据库·redis·缓存
CRMEB系统商城5 小时前
开源自建还是SaaS订阅?算一笔3年经济账
java·大数据·开发语言·开源
@Mike@5 小时前
02-数据库学习笔记(SQL引擎)
数据库·笔记·学习
Darling噜啦啦5 小时前
揭秘 LLM 的随机性黑盒:从 Temperature + Top-K 到 LangChain Chain 工作流实战
langchain·llm
王维同学6 小时前
[自学][Windows C++]RunOnceEx 注册表分组键的安全遍历
c++·windows·安全·开源
我的xiaodoujiao6 小时前
快速学习Python基础知识详细图文教程9--函数进阶
开发语言·python·学习·测试工具