news 2026/4/30 9:18:40

小白学大模型:从头搭建Qwen3(MoE、GQA、RoPE 和 Multi-Head Attention)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
小白学大模型:从头搭建Qwen3(MoE、GQA、RoPE 和 Multi-Head Attention)

阿里云推出的Qwen 3(通义千问3) 是目前性能最强大的开源模型之一,在多种任务上都表现出色,例如推理、编程、数学和多语言理解。

在这篇博客文章中,我们将从头开始构建一个 0.8 亿参数、包含两个专家层的 Qwen 3 MoE 模型。

模型亮点

  • 旗舰版本:Qwen3-235B-A22B 在MMLU-ProLiveCodeBenchAIME等重要基准测试中名列前茅,其性能甚至能与顶尖的专有模型相媲美。1
  • 架构创新:Qwen 3 采用了Mixture-of-Experts (MoE)架构。这种架构的优势在于,在处理每个查询时,它只会激活部分(而非全部)参数,从而在保证高性能的同时,实现了更高的效率。

  • 强大功能:
  • 支持高达128K的上下文长度。
  • 支持119种语言。
  • 引入了独特的“思考”与“非思考”双模式,以平衡深度推理和更快的推理速度。4

前提条件

这篇博客的教程假设读者具备神经网络和Transformer架构的基础知识,并且熟悉Python编程,但无需掌握面向对象编程(OOP)。教程中提供了相关的视频链接作为学习资源。

Qwen 3 MoE(混合专家)架构的核心思想是:与其使用一个庞大且通用的网络来处理所有任务,不如使用一个由多个**小型、专业网络(专家)组成的团队,并由一个“路由器”**来分配任务。

  • 专家(Experts):这些是较小的、专门化的神经网络,通常是简单的前馈网络(FFNs)或多层感知机(MLPs)。每个专家擅长处理特定类型的信息或模式。
  • 路由器(Router):这是一个小型网络,充当“管理者”的角色。它的任务是接收输入数据(例如一个词的嵌入向量),然后决定将这个任务分配给哪一个或哪几个最适合的专家。

通过一个句子“the cat sat”来理解MoE的工作流程:

  1. 分词(Tokenization):首先,句子被分解成单独的词元(tokens):"The","cat","sat"
  2. 词元嵌入(Token Embedding):每个词元被转换为一个向量,这个向量包含了词的语义信息。例如,"cat"被表示为一个高维的嵌入向量。
  3. 路由器选择专家:"cat"的向量进入MoE层时,路由器会对其进行分析。假设有4个专家(E1, E2, E3, E4),路由器可能会根据"cat"的特征,认为E2(擅长处理名词)和E4(擅长处理动物概念)是最佳选择。
  4. 分配任务:路由器会给被选中的专家分配分数或“权重”(例如,E2获得70%的权重,E4获得30%的权重)。然后,"cat"的向量只会被发送给E2和E4,而E1和E3则无需参与计算,从而节省了大量的计算资源。
  5. 专家处理:E2和E4分别处理"cat"的向量,并生成各自的输出(Output_E2Output_E4)。
  6. 结果加权合并:最后,两个专家的输出会根据路由器的权重进行加权合并,得到最终的输出:Final_Output = (0.7 * Output_E2) + (0.3 * Output_E4)。这个最终输出会继续传递到模型的下一个层。

一个词元在Qwen 3 MoE模型中的完整旅程如下:

  1. 输入文本(Input Text)**进入**分词器(Tokenizer)
  2. 分词器生成数字词元ID(Token IDs)
  3. 词嵌入层(Embedding Layer)**将ID转换为具有意义的**向量(Embeddings),并添加位置信息(Positional Info),这通常通过RoPE(旋转位置编码)实现。
  4. 这些向量流经多个Transformer模块。每个模块包含:
  • 自注意力机制(Self-Attention):词元之间相互“关注”,其性能通过RoPE得到增强。
  • MoE层:路由器将词元发送给特定的专家。
  • 归一化(Normalization):使用RMSNorm等技术来稳定训练。
  • 残差连接(Residual connections):帮助信息在网络中流动。
  1. 最后一个模块的输出进入最终层(Final Layer)
  2. 最终层生成词汇表中每个词元的Logits(分数)
  3. Logits被转换为概率,并预测出下一个词元。

环境设置与文件下载

本节介绍如何为构建 Qwen 3 MoE 模型做准备。首先需要安装必要的 Python 库,然后下载模型的核心文件。

# 下载所需的模块pip install sentencepiece tiktoken torch matplotlib huggingface_hub tokenizers safetensors

本指南将使用一个较小的 Qwen 3 MoE 版本,该版本包含两个专家(Experts),每个专家有0.8亿参数。你可以通过两种方式下载所需的文件:

# 导入tqdm用于进度条,snapshot_download用于下载模型文件from tqdm import tqdmfrom huggingface_hub import snapshot_download# 定义Hugging Face仓库ID和本地保存目录repo_id = "huihui-ai/Huihui-MoE-0.8B-2E"local_dir = "Huihui-MoE-0.8B-2E"# 从Hugging Face下载模型快照# 忽略.bin文件,只下载config、tokenizer和safetensors权重snapshot_download( repo_id=repo_id, local_dir=local_dir, ignore_patterns=["*.bin"], # 跳过大型的.bin文件,只获取safetensors tqdm_class=tqdm # 使用标准的tqdm显示进度条)

模型文件与参数

Qwen 3 使用的是字节对编码 (Byte Pair Encoding, BPE)算法。BPE 是一种子词分词算法,它通过迭代地将语料库中最频繁的相邻字符对合并成新的词元来构建词汇表。这使得模型能够有效地处理未知词汇并保持词汇表大小适中。

  • 用途:将原始文本(如"the only thing I know is that I know")转换为模型能理解的数字序列([785, 1172, 3166, 358, 1414, 374, 429, 358, 1414]),并能将这些数字序列解码回文本。
  • 特点:词汇表大小为 151669,包含通过 BPE 算法合并形成的子词单元。

首先,我们需要将输入的文本转换成模型能够理解的词元(tokens)。Qwen 3 模型使用特定的聊天模板来构建对话,这有助于模型区分用户的输入和自己的响应。

  • 聊天模板:Qwen 3 的模板使用了<|im_start|><|im_end|>等特殊词元来定义对话的边界。例如,一个用户提问的格式通常是<|im_start|>user\n{prompt}<|im_end|>\n<|im_start|>assistant\n
  • 词元化过程:代码首先获取这些特殊词元的 ID,然后将用户的提示 ("The only thing I know is that I know") 编码成词元 ID 列表。最后,将所有这些 ID 按模板结构拼接成一个完整的序列。
  • 结果:一个包含所有词元 ID 的 PyTorchtensor,代表了完整的对话上下文。

词元化之后,我们需要将每个词元 ID 转换成一个词嵌入向量。词嵌入是一个稠密的、高维度的向量,它捕捉了词元的语义和上下文信息。

  • 嵌入层:我们通过nn.Embedding模块创建一个嵌入层。这个层的尺寸由模型的词汇表大小 (vocab_size) 和隐藏层维度 (dim) 决定。
  • 加载预训练权重:为了利用 Qwen 3 模型的知识,我们直接将下载好的预训练权重文件 (model_weights["model.embed_tokens.weight"]) 加载到我们新创建的嵌入层中。
  • 生成嵌入:将词元 ID 的张量输入到这个嵌入层,就会得到一个形状为[17, 1024]的张量,其中 17 是词元数量,1024 是词嵌入的维度。

在将词嵌入向量输入到 Transformer 层之前,对其进行归一化是一个关键步骤,它能确保训练的稳定性和效率。Qwen 3 使用RMSNorm(Root Mean Square Layer Normalization) 来完成这个任务。

  • RMSNorm 函数rms_norm函数通过计算输入张量的均方根 (RMS) 来进行归一化。它将输入张量乘以其均方根的倒数,从而使归一化后的张量具有单位方差。
  • 作用:RMSNorm 简化了传统的 LayerNorm,省略了减去均值的步骤,只进行重新缩放,这在保持性能的同时,提供了更高的计算效率。
  • 应用:我们使用模型权重中第一层 (model.layers.0.input_layernorm.weight) 的归一化权重,对生成的词嵌入向量进行归一化。这为接下来的注意力机制做好了准备。

分组查询注意力(Grouped-Query Attention, GQA)

Qwen 3 模型采用GQA机制来优化计算效率。传统的自注意力机制中,每个查询头(Query head)都有一个对应的键头(Key head)和值头(Value head)。而 GQA 允许多个查询头共享一小组键头和值头。

  • 实现方式
  • 模型有16个查询头 (n_heads = 16),因此q_proj权重被重塑为[16, 128, 1024]
  • 模型有8个键头和值头 (n_kv_heads = 8),所以k_projv_proj权重被重塑为[8, 128, 1024]
  • 计算:我们首先从这些重塑后的权重中,提取第一个查询头和第一个键/值头的权重,然后将归一化后的词嵌入向量与这些权重相乘,得到每个词元对应的 Q、K、V 向量。
# Get the pre-computed rotations for our sequence of 17 tokensfreqs_cis_for_tokens = freqs_cis[:len(tokens)]# --- Apply RoPE to Query vectors ---# Reshape [17, 128] to [17, 64, 2] and view as complex numbers [17, 64]q_per_token_as_complex_numbers = torch.view_as_complex(q_per_token.float().view(q_per_token.shape[0], -1, 2))# Apply rotation via complex multiplicationq_per_token_rotated_complex = q_per_token_as_complex_numbers * freqs_cis_for_tokens# Convert back to real numbers and reshape to [17, 128]q_per_token_rotated = torch.view_as_real(q_per_token_rotated_complex).view(q_per_token.shape)# --- Apply RoPE to Key vectors (same process) ---k_per_token_as_complex_numbers = torch.view_as_complex(k_per_token.float().view(k_per_token.shape[0], -1, 2))k_per_token_rotated_complex = k_per_token_as_complex_numbers * freqs_cis_for_tokensk_per_token_rotated = torch.view_as_real(k_per_token_rotated_complex).view(k_per_token.shape)print("Shape of rotated Query vectors:", q_per_token_rotated.shape)#### OUTPUT ##### Shape of rotated Query vectors: torch.Size([17, 128])#### OUTPUT ####

在计算注意力之前,需要为 Q 和 K 向量注入位置信息,以使模型能够理解词元在序列中的顺序。Qwen 3 使用RoPE(Rotary Position Embedding) 来实现这一功能。

  • RoPE 原理:RoPE 通过旋转 Q 和 K 向量的每一对维度来编码位置信息。每个 2D 维度对(例如,维度0和1,维度2和3)的旋转角度会根据其位置和维度而变化。
  • 实现步骤
  1. 预先计算一个包含旋转角度的查找表 (freqs_cis)。这个表包含了所有可能位置的旋转复数。
  2. 将 Q 和 K 向量重塑为复数形式。
  3. 通过复数乘法,将预计算的旋转角度应用到 Q 和 K 向量上。
  4. 将旋转后的复数向量转换回实数向量。

现在,我们可以计算每个词元对其他所有词元的重要性。

  1. 点积:将旋转后的 Q 向量与 K 向量的转置相乘,得到一个[17, 17]的矩阵,其中每个元素表示一个词元对另一个词元的注意力分数。
  2. 缩放:将分数除以head_dim的平方根 (128**0.5),以防止内积过大,导致 softmax 函数梯度消失。
  3. 因果掩码(Causal Masking):由于我们构建的是一个自回归模型,词元不应该“看到”未来的词元。因此,我们创建一个上三角矩阵,并将对角线以上的所有元素设置为负无穷,从而确保模型在预测当前词元时只关注其前面的词元。
  4. Softmax:将掩码后的分数应用 Softmax 函数,将其转换为 0 到 1 之间的概率,这些概率被称为注意力权重

实现多头注意力(Multi-Head Attention)

多头注意力机制通过并行运行多个独立的注意力计算来捕捉输入序列中不同位置和方面的信息。

  • 并行计算:代码通过一个for循环遍历所有的16个注意力头。在每个循环中,它提取当前头的Q、K、V权重,应用RoPE位置编码,计算注意力分数和权重,并最终生成一个大小为[17, 128]的输出张量。
  • GQA:由于采用了 **分组查询注意力 (GQA)**,k_projv_proj权重只被分为8个共享的头。代码通过head // (n_heads // n_kv_heads)(即head // 2)来确保每两个查询头共享一个键/值头。
  • 拼接与投影:所有16个头的输出被收集在一个列表中,然后通过torch.cat沿着最后一个维度拼接成一个更大的张量[17, 2048]。这个张量再通过一个输出投影层 (o_proj) 投影回模型的隐藏层维度[17, 1024]
  • 残差连接:投影后的结果 (embedding_delta) 被加回到注意力层的输入 (token_embeddings_unnormalized),形成了第一个残差连接。这有助于训练非常深的网络。
# --- Step 1: The MoE Router ---# The router is a simple linear layer that determines which expert to send each token to.# It projects our [17, 1024] tensor to a [17, num_experts] tensor of scores (logits).gate = model_weights["model.layers.0.mlp.gate.weight"]router_logits = torch.matmul(embedding_after_attention_normalized, gate.T)# We apply softmax to the logits to get probabilities, and then find the expert with the# highest probability for each token.routing_weights = torch.nn.functional.softmax(router_logits.float(), dim=1).to(torch.bfloat16)routing_expert_indices = torch.argmax(routing_weights, dim=1)print("Router logits shape:", router_logits.shape)print("Expert chosen for each of the 17 tokens:", routing_expert_indices)# --- Step 2: The Expert Layers ---# Each expert is a SwiGLU-style Feed-Forward Network.expert0_w1 = model_weights["model.layers.0.mlp.experts.0.gate_proj.weight"]expert0_w2 = model_weights["model.layers.0.mlp.experts.0.down_proj.weight"]expert0_w3 = model_weights["model.layers.0.mlp.experts.0.up_proj.weight"]expert1_w1 = model_weights["model.layers.0.mlp.experts.1.gate_proj.weight"]expert1_w2 = model_weights["model.layers.0.mlp.experts.1.down_proj.weight"]expert1_w3 = model_weights["model.layers.0.mlp.experts.1.up_proj.weight"]# --- Step 3: Process tokens with their chosen expert ---final_expert_output = torch.zeros_like(embedding_after_attention_normalized)#### OUTPUT ##### Router logits shape: torch.Size([17, 2])# Expert chosen for each of the 17 tokens: tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])#### OUTPUT ####

MoE是Qwen 3架构的核心,它在注意力层之后被应用。

  • 预归一化:首先,对注意力层输出进行RMSNorm 归一化,为MoE层做准备。
  • 路由器(Router):一个名为gate的线性层充当路由器。它将归一化后的嵌入向量([17, 1024])投影成一个包含专家分数的张量([17, 2])。然后,通过softmax获得每个词元分配给每个专家的概率,并使用argmax选出概率最高的专家。
  • 专家(Experts):每个专家都是一个SwiGLU风格的前馈网络。代码加载了两个专家的权重,并为每个词元循环处理。
  • 加权求和:每个词元只会被其被选中的专家处理。专家的输出会乘以其对应的路由器概率,最终被整合到final_expert_output张量中。
  • 残差连接:MoE模块的输出被加回到其输入 (embedding_after_attention),形成了第二个残差连接,完成了整个Transformer层。
# The LM Head weights are the same as the embedding weights (weight tying)lm_head_weights = model_weights["model.embed_tokens.weight"]# We only care about the last token's output to predict the next tokenlast_token_embedding = final_embedding_normalized[-1]# Calculate the logits by multiplying with the LM Headlogits = torch.matmul(last_token_embedding, lm_head_weights.T)print("Shape of the final logits:", logits.shape)#### OUTPUT ##### Shape of the final logits: torch.Size([151936])#### OUTPUT ####

最后,所有的步骤被整合到一个主循环中,循环遍历模型的28个层。

  • 层循环for layer in range(n_layers)循环负责处理模型的每一层。在每个循环中,它都执行完整的注意力子层和MoE子层。
  • 数据流:前一层的输出 (final_embedding) 会作为下一层的输入,并在每个子层中通过残差连接不断更新。
  • 结果:经过所有28个层的处理后,我们得到一个形状为[17, 1024]的最终嵌入向量,这个向量包含了所有词元的完整上下文信息,并准备好进入最终层进行下一个词元的预测。
# Find the token ID with the highest scorenext_token_id = torch.argmax(logits, dim=-1)print(f"Predicted Token ID: {next_token_id.item()}")# Decode the ID back to a string to see the predicted wordpredicted_word = tokenizer.decode([next_token_id.item()])print(f"\nPredicted Word: '{predicted_word}'")#### OUTPUT ##### Predicted Token ID: 12454# Predicted Word: 'nothing'#### OUTPUT ####

开源地址:https://github.com/FareedKhan-dev/qwen3-MoE-from-scratch

想入门 AI 大模型却找不到清晰方向?备考大厂 AI 岗还在四处搜集零散资料?别再浪费时间啦!2025 年AI 大模型全套学习资料已整理完毕,从学习路线到面试真题,从工具教程到行业报告,一站式覆盖你的所有需求,现在全部免费分享

👇👇扫码免费领取全部内容👇👇

一、学习必备:100+本大模型电子书+26 份行业报告 + 600+ 套技术PPT,帮你看透 AI 趋势

想了解大模型的行业动态、商业落地案例?大模型电子书?这份资料帮你站在 “行业高度” 学 AI

1. 100+本大模型方向电子书

2. 26 份行业研究报告:覆盖多领域实践与趋势

报告包含阿里、DeepSeek 等权威机构发布的核心内容,涵盖:

  • 职业趋势:《AI + 职业趋势报告》《中国 AI 人才粮仓模型解析》;
  • 商业落地:《生成式 AI 商业落地白皮书》《AI Agent 应用落地技术白皮书》;
  • 领域细分:《AGI 在金融领域的应用报告》《AI GC 实践案例集》;
  • 行业监测:《2024 年中国大模型季度监测报告》《2025 年中国技术市场发展趋势》。

3. 600+套技术大会 PPT:听行业大咖讲实战

PPT 整理自 2024-2025 年热门技术大会,包含百度、腾讯、字节等企业的一线实践:

  • 安全方向:《端侧大模型的安全建设》《大模型驱动安全升级(腾讯代码安全实践)》;
  • 产品与创新:《大模型产品如何创新与创收》《AI 时代的新范式:构建 AI 产品》;
  • 多模态与 Agent:《Step-Video 开源模型(视频生成进展)》《Agentic RAG 的现在与未来》;
  • 工程落地:《从原型到生产:AgentOps 加速字节 AI 应用落地》《智能代码助手 CodeFuse 的架构设计》。

二、求职必看:大厂 AI 岗面试 “弹药库”,300 + 真题 + 107 道面经直接抱走

想冲字节、腾讯、阿里、蔚来等大厂 AI 岗?这份面试资料帮你提前 “押题”,拒绝临场慌!

1. 107 道大厂面经:覆盖 Prompt、RAG、大模型应用工程师等热门岗位

面经整理自 2021-2025 年真实面试场景,包含 TPlink、字节、腾讯、蔚来、虾皮、中兴、科大讯飞、京东等企业的高频考题,每道题都附带思路解析

2. 102 道 AI 大模型真题:直击大模型核心考点

针对大模型专属考题,从概念到实践全面覆盖,帮你理清底层逻辑:

3. 97 道 LLMs 真题:聚焦大型语言模型高频问题

专门拆解 LLMs 的核心痛点与解决方案,比如让很多人头疼的 “复读机问题”:


三、路线必明: AI 大模型学习路线图,1 张图理清核心内容

刚接触 AI 大模型,不知道该从哪学起?这份「AI大模型 学习路线图」直接帮你划重点,不用再盲目摸索!

路线图涵盖 5 大核心板块,从基础到进阶层层递进:一步步带你从入门到进阶,从理论到实战。

L1阶段:启航篇丨极速破界AI新时代

L1阶段:了解大模型的基础知识,以及大模型在各个行业的应用和分析,学习理解大模型的核心原理、关键技术以及大模型应用场景。

L2阶段:攻坚篇丨RAG开发实战工坊

L2阶段:AI大模型RAG应用开发工程,主要学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3阶段:跃迁篇丨Agent智能体架构设计

L3阶段:大模型Agent应用架构进阶实现,主要学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造Agent智能体。

L4阶段:精进篇丨模型微调与私有化部署

L4阶段:大模型的微调和私有化部署,更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调,并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

L5阶段:专题集丨特训篇 【录播课】


四、资料领取:全套内容免费抱走,学 AI 不用再找第二份

不管你是 0 基础想入门 AI 大模型,还是有基础想冲刺大厂、了解行业趋势,这份资料都能满足你!
现在只需按照提示操作,就能免费领取:

👇👇扫码免费领取全部内容👇👇

2025 年想抓住 AI 大模型的风口?别犹豫,这份免费资料就是你的 “起跑线”!

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

Foundation 网格 - 中型设备

Foundation 网格系统在中型设备&#xff08;Medium Devices&#xff09;上的行为 Foundation XY Grid 的 medium 断点 默认对应屏幕宽度 ≥ 640px&#xff08;通常指平板电脑&#xff0c;如 iPad 竖屏或横屏入门级&#xff09;&#xff0c;直到 large 断点&#xff08;≥ 1024…

作者头像 李华
网站建设 2026/4/20 16:28:32

Foundation 块状网格

Foundation XY Grid 中的块状网格&#xff08;Block Grid&#xff09; Foundation 的 块状网格&#xff08;Block Grid&#xff09;是一种快捷方式&#xff0c;用于创建均匀分布的等宽列&#xff08;如图片画廊、产品卡片列表等&#xff09;&#xff0c;无需为每个单元格单独指…

作者头像 李华
网站建设 2026/4/23 13:45:54

2025网络安全面试指南(非常详细)收藏这一篇就够了

1.1 网络安全行业现状 安全行业起步晚。安全行业整体起来才没几年&#xff0c;多数企业因为资源投入和建设时间原因导致覆盖面和深入度都不够&#xff0c;这其中甚至包括一些国内大厂&#xff0c;并没有想象的那么安全。其安全水位仅能应付一些白帽子级别&#xff0c;针对专业…

作者头像 李华
网站建设 2026/4/21 22:17:47

升级了 !Spring 6.0 + Boot 3.0,性能太强了!

&#x1f449; 这是一个或许对你有用的社群&#x1f431; 一对一交流/面试小册/简历优化/求职解惑&#xff0c;欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料&#xff1a; 《项目实战&#xff08;视频&#xff09;》&#xff1a;从书中学&#xff0c;往事上…

作者头像 李华
网站建设 2026/4/28 11:57:22

黑马微服务p10mybatisplus09核心功能iservice 测试文档无法正常打开

问题描述在网课下面的这个位置&#xff0c;无法正常显示&#xff0c;具体下一张图片就像这样无法正常显示解决经过检查发现&#xff0c;是我的配置这里不太一样&#xff0c;我在yaml文件中的配置是直接在网课资料里面复制粘贴的&#xff0c;而我创建controller类的时候&#xf…

作者头像 李华
网站建设 2026/4/25 8:05:45

魔盒项目开发纪实:后端项目设计与开发

继续后端设计与开发&#xff1a;魔盒项目是一个基于物联网技术的智能设备管理系统&#xff0c;后端采用 Go 语言和 Beego 框架开发&#xff0c;提供了完整的设备管理、用户认证、OTA 固件升级等功能。本文将详细介绍后端开发的进度和实现情况。 技术栈 开发语言&#xff1a;G…

作者头像 李华