从零开始写Qwen3(二)快速搭建Qwen3
概述在从零开始写Qwen3一模型结构分析中已经识别了Qwen3的基本结构了解了使用哪些关键组件现在开始实现将模型分为这几个模块attn注意力计算不包含短接和QKV嵌入无参数self_attn自注意力调用attnnorm主要实现RMSNormropefeedback实现SwiGLUtransformer_block一个完整的Transformer Decoder层qwen3完整的模型本章的目标就是快速搭建一个模型能够推理即可之后再自己手写组件从零开始写Qwen3目录模型组件Attn直接使用现成的fromtorch.nn.functionalimportscaled_dot_product_attentionreturnscaled_dot_product_attention(q,k,v,is_causalis_causal,enable_gqaTrue,scaleself.n_head_embed**-0.5,)需要注意qkv以及输出o的维度是 BxHxSxDH是多头在enable_gqa时Q的头可以是KV的整倍数O的头数和Q相同is_causal表示是否开启遮罩。a. 这里非常奇怪的一点理论上在decode阶段开启KVCacheQ长度只有1这个参数有没有无所谓但如果传了True会导致结果错误所以我们在decode阶段将其手动设置为Falsescale就是自注意力中的那个缩放D \sqrt{D}D​norm有现成的def__init__(...):self.weightnn.Parameter(torch.ones(norm_dim))defforward(...):returnnn.functional.rms_norm(x,self.weight.shape,self.weight,self.epseps是为了防止分母为0添加的一个数这个参数一般模型config.json会提供Qwen3-0.6B是1e-6rope这个没有现成的需要手写原理RoPE是模仿向量内积的那个夹角cos ⁡ θ \cos\thetacosθ弄的让两个向量旋转它们位置对应的角度然后内积就可以体现它们之间相对位置了对于二维向量可以在平面上执行旋转但高维向量无法保证都在同一个平面上其实并不需要旋转高维向量x ⋅ y ∑ i 1 d x i y i ∑ k 1 d / 2 ( x 2 k − 1 y 2 k − 1 x 2 k y 2 k ) \mathbf{x} \cdot \mathbf{y} \sum_{i1}^{d} x_i y_i \sum_{k1}^{d/2} \left( x_{2k-1} y_{2k-1} x_{2k} y_{2k} \right)x⋅yi1∑d​xi​yi​k1∑d/2​(x2k−1​y2k−1​x2k​y2k​)两个高维向量的内积其实可以看做多个二维向量内积之和大模型隐藏层维度一般是偶数如果真是奇数可以补充一个0上去rope的做法就是把特征向量当成多个二维向量对每个二维向量进行旋转对一个二维向量的旋转就是乘一个矩阵R ( θ ) [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] R(\theta) \begin{bmatrix} \cos\theta -\sin\theta\\ \sin\theta \cos\theta \end{bmatrix}\\R(θ)[cosθsinθ​−sinθcosθ​]实际上每个小向量可以旋转不同的角度比如低维度的可以旋转大一点的角度高维度旋转小一点的角度这样在相同cos ⁡ θ \cos \thetacosθ时高维度必须距离更远才能达到和低维度相同的系数低维度可以捕获短距离、局部的关系高维度则捕获长距离、全局的关系一般是这样生成基础旋转角的θ β − 2 i / d \theta\beta^{-2i/d}θβ−2i/di是维度组向下除以2取整d是维度beta是10000乃至更大这个参数也在config.json中有记录对每个在位置n的词元嵌入旋转n θ n\thetanθ实现注意到旋转之后有这个x ′ cos ⁡ θ x − sin ⁡ θ y y ′ sin ⁡ θ x cos ⁡ θ y x ′ ⃗ [ x ′ ; y ′ ] cos ⁡ θ x ⃗ sin ⁡ θ σ ( x ⃗ ) x\cos \theta x -\sin\theta y\\ y\sin \theta x \cos \theta y\\ \vec{x}[x;y]\cos \theta \vec{x} \sin \theta \sigma(\vec{x})x′cosθx−sinθyy′sinθxcosθyx′[x′;y′]cosθxsinθσ(x)这里σ \sigmaσ是奇偶交换并把交换后的偶数部分取负实际上σ \sigmaσ除了奇偶交换原始版本还有其他方式比如GPT-Neox的交换前一半和后一半Qwen3也用这个在llama.cpp中将交换奇偶的版本叫做normal交换前后一半的叫做neox将上面的公式扩展后就有了rope的实现x ′ ⃗ cos ⁡ θ ⃗ ∘ x ⃗ sin ⁡ θ ⃗ ∘ σ ( x ⃗ ) \vec{x}\cos \vec{\theta} \circ \vec{x} \sin \vec{\theta}\circ \sigma(\vec{x})x′cosθ∘xsinθ∘σ(x)这个rope在单次前向计算中对所有层不管是K还是V这个cos ⁡ θ ⃗ , sin ⁡ θ ⃗ \cos\vec{\theta},\sin\vec{\theta}cosθ,sinθ都是相同的所以全局计算一次即可如果可以保证生成长度不会超过最大长度那甚至可以预先计算最大长度的这两个向量然后后面直接截取其中一部分使用即可简单计算defbuild_cos_sin_embed(self,dtype,position_ids:torch.Tensor)-tuple[torch.Tensor,torch.Tensor]:inv_freq1.0/(self.base_freq**(torch.arange(0,self.head_dim,2,deviceposition_ids.device).float()/self.head_dim)).unsqueeze(0)freqstorch.einsum(bj,bk-bjk,position_ids,inv_freq)embtorch.cat([freqs,freqs],dim-1)return(emb.cos().to(dtype),emb.sin().to(dtype))这里做了一个乘法其实就是n θ n\thetanθ为每个位置生成一个旋转向量einsum是爱因斯坦求和用于张量计算的bj,bk-bjk 的意思是输入两个矩阵下标分别是bj和bk然后乘出来一个三维数组下标是 bjk也就是相同 b 的数乘到一起C b j k A b j B b k C_{bjk}A_{bj}B_{bk}Cbjk​Abj​Bbk​如果是 jb,bk-jk那就是常规的矩阵乘法了C j k ∑ j A b j B j k C_{jk}\sum_j A_{bj}B_{jk}Cjk​∑j​Abj​Bjk​通常后面这个求和符号可以省略selfAttn这个需要自己手写也简单QKV进行投影QK需要进行后norm然后把QKV通过viewtranpose转为 BHSD 的格式对QK执行rope然后计算attn得到oo转置到BSHD然后reshape到BSD后投影输出所有的投影直接使用Linear即可其他feedback其实没什么特别的组件Linear和Swish激活函数就没了transformer_block 就是上面组件拼接即可qwen3在从零开始写Qwen3一模型结构分析中展示了forward就是一个Embedding嵌入执行多层TransformerBlock最后NormLinear就行运行推理加载参数HuggingFace下载的模型文件夹下有safetensors文件Qwen3-0.6B较小只有一个文件这就是模型参数里面包含所有张量和张量的名字通过张量的名字来加载到参数中实际上这些张量的名字就是transformers中成员变量的名字这些成员要么嵌套包含其他组件要么包含一个叫做.weight的成员类型是nn.Parameter后者就是要加载的参数实际上所有的张量名字都是以.weight结尾的比如一个张量的名字是model.layers.8.self_attn.k_norm.weight它就是编号为8从0开始的解码层的自注意力组件的k_norm的参数执行推理有个完整的模型就可以推理了整个模型的输入是嵌入id列表可以直接使用from tokenizers import Tokenizer这个库这个库和transformers的AutoTokenizer效果是一样的因为都是加载了模型目录下的tokenizer.jsontokenizerTokenizer.from_file(model_path/tokenizer.json)print(prompt)inputstensor.tensor([tokenizer.encode(prompt)])输出参数是BxSxD的logits只需要最后一个S的特征向量它的长度就是字典长度每个值代表一个词元可以简单argmax得到最可能的下一个词元id然后把这个词元id拼接到 inputs预测下一个词元不断如此直到达到最大长度或者遇到 eos提示词可以直接写字符串这是大模型的补全模式但模型目录下还有一个tokenizer_config.json文件其中有一个chat_template成员这是一个Jinja语法的模板字符串它可以填充模板实现多轮对话的格式也是对话模式可以直接加载上withopen(model_path/tokenizer_config.json)asf:datajson.load(f)templatejinja2.Template(data[chat_template])prompttemplate.render(messages[{role:user,content:介绍一下你自己}])tokenizerTokenizer.from_file(model_path/tokenizer.json)这个模板实际上就是我们常用的ChatMessage格式。模板中还支持工具调用写tool_calls就行不知道Qwen3-0.6B的模型的工具调用能力如何有机会写个Agent看看这个模板基本是这样的截取前半部分{%-iftools%}{{-|im_start|system\n}}{%-ifmessages[0].rolesystem%}{{-messages[0].content\n\n}}{%-endif%}{{-# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within tools/tools XML tags:\ntools}}{%-fortoolintools%}{{-\n}}{{-tool|tojson}}{%-endfor%}{{-\n/tools\n\nFor each function call, return a json object with function name and arguments within tool_call/tool_call XML tags:\ntool_call\n{\name\: function-name, \arguments\: args-json-object}\n/tool_call|im_end|\n}}{%-else%}{%-ifmessages[0].rolesystem%}{{-|im_start|system\nmessages[0].content|im_end|\n}}{%-endif%}{%-endif%}这是Jinja语法上面的内容大概是这样如果有tools这个变量传入才处理如果第一个messages也就是可以传数组的role是system把系统提示词放到总体提示词开头接着写入工具提示词把工具描述放进去直接json但这个json通常都是有严格格式要求的否则也就是没有传入工具简单把系统提示词传入注意到每轮对话都是以|im_start|role开头|im_end|结尾eos就是这个|im_end|现在没有做KVCache运行速度很慢而且越来越慢这是我们下一节要解决的问题

相关新闻

2026工控高薪:C#上位机面试15题(含答案)

2026工控高薪:C#上位机面试15题(含答案)

本文适配人群:备战2026工控C#上位机高薪岗位的开发者、想跳槽涨薪的工控工程师、刚入行想对标高薪能力的新人 核心价值:2026年工控行业C#上位机岗位薪资持续走高(一线城市15-30K,头部企业40K),但面试通过率…

2026/7/6 14:25:28 阅读更多 →
【优选算法】专题九——链表

【优选算法】专题九——链表

文章目录一、链表题目的常用解题技巧总结二、两数相加解题思路代码实现及解析总结三、两两交换链表中的节点总结四、重排链表解题思路代码实现及解析总结五、合并 K 个升序链表解题思路代码实现及解析总结六、K 个一组翻转链表解题思路代码实现及解析总结一、链表题目的常用解题…

2026/7/4 9:58:15 阅读更多 →
Scrapling+OpenClaw:2026年最强本地AI数据管道,爬虫直接对接智能体

Scrapling+OpenClaw:2026年最强本地AI数据管道,爬虫直接对接智能体

今年开年给一个做户外用品的老客户搭AI选品智能体,踩了我做爬虫+AI这几年最憋屈的一个坑。 客户的需求很明确:做一套完全本地化的竞品监控选品系统,每天自动爬3个垂直平台的新品数据,洗干净、结构化之后直接喂给选品智能体,能自动做价格带分析、卖点拆解、库存预警,所有…

2026/5/17 12:18:01 阅读更多 →

最新新闻

ADP Agent Portal入门:跨平台智能体部署全流程

ADP Agent Portal入门:跨平台智能体部署全流程

ADP Agent Portal是腾讯云2026年4月7日发布的跨平台企业智能体门户,支持一次性部署智能体到企业微信、飞书、腾讯会议等12个主流办公平台,无需重复开发。本文提供从注册到跨平台部署的全流程指南,包含可直接复用的API调用代码。 一、部署前准…

2026/7/7 13:50:38 阅读更多 →
PARP12在细胞死亡与抗病毒免疫中的调控机制及其治疗潜力

PARP12在细胞死亡与抗病毒免疫中的调控机制及其治疗潜力

PARP家族与PARP12的发现历程多聚ADP核糖聚合酶(Poly(ADP-ribose) polymerases, PARPs)是一类具有ADP核糖基转移酶活性的蛋白质家族,在DNA损伤修复、基因组稳定性维持、细胞死亡调控和免疫应答等多种生理病理过程中发挥关键作用。人…

2026/7/7 13:48:37 阅读更多 →
直流电机静音控制方案:TB9051FTG与PIC18LF47K40应用

直流电机静音控制方案:TB9051FTG与PIC18LF47K40应用

1. 项目概述:直流电机静音控制方案在工业自动化和消费电子领域,直流电机的噪声问题一直是工程师面临的挑战。传统PWM调速方案虽然简单高效,但开关噪声和电磁干扰问题显著。本项目采用东芝TB9051FTG电机驱动IC搭配Microchip的PIC18LF47K40微控…

2026/7/7 13:44:37 阅读更多 →
Si4732收音机芯片与PIC18F57Q43微控制器的设计与优化

Si4732收音机芯片与PIC18F57Q43微控制器的设计与优化

1. Si4732收音机芯片的核心特性解析 Si4732是Silicon Labs推出的一款高性能数字信号处理(DSP)收音机接收芯片,它彻底改变了传统模拟收音机的设计方式。这款芯片在业余无线电爱好者、便携式收音机制造商和专业通信设备厂商中享有极高声誉,主要得益于以下几…

2026/7/7 13:42:36 阅读更多 →
2026图片去水印工具教程:手机电脑软件、在线网站AI效果对比

2026图片去水印工具教程:手机电脑软件、在线网站AI效果对比

日常保存的截图、素材图、平台实拍图,大多会自带平台水印、文字水印、logo水印,影响图片整洁度与使用观感。很多个人用户都在寻找免费好用的图片去水印工具,但市面上工具繁杂,要么收费限次、要么画质压缩严重、要么操作复杂。本文…

2026/7/7 13:40:35 阅读更多 →
A3910与STM32L162ZE在电机控制中的高效应用

A3910与STM32L162ZE在电机控制中的高效应用

1. 认识A3910与STM32L162ZE这对黄金搭档第一次看到A3910和STM32L162ZE这两个型号时,我正为一个工业控制项目选型发愁。A3910是Allegro MicroSystems推出的全桥电机驱动芯片,而STM32L162ZE则是STMicroelectronics的超低功耗ARM Cortex-M3微控制器。它们看…

2026/7/7 13:40:35 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/7 12:34:47 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻