news 2026/10/1 14:43:59

Transformer 论文精读:Attention Is All You Need 翻译与架构拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Transformer 论文精读:Attention Is All You Need 翻译与架构拆解

1. 从论文到代码:为什么读 Attention Is All You Need 总卡在公式上

如果你正在搜「Attention Is All You Need 中文翻译」或者「Transformer 论文精读」,大概率遇到过这种情况:摘要和引言读得挺顺,一到 3.2 节 Scaled Dot-Product Attention 就开始卡壳,公式里的 Q、K、V 到底怎么来的、softmax 为什么除根号 dk、多头到底在「多」什么,光看文字很难在脑子里跑起来。这篇 Transformer 论文精读会换一个思路:把逐段翻译和可运行代码绑在一起,每读一段就写一段 PyTorch,让公式在张量上真正跑一遍。

Attention Is All You Need 是 2017 年 Google 团队提出的架构论文,它做的事情用一句话说就是:把序列转换模型里用了多年的 RNN 和 CNN 全部拿掉,只留注意力机制。适合谁读?想搞懂大模型底层原理的开发者、准备手撕 Transformer 的面试者、以及需要把论文公式落到工程代码的算法同学。我试过纯读论文三遍还是记不住位置编码的公式,后来改成边翻译边写代码,才真正把 encoder-decoder 堆栈、多头注意力、残差加 LayerNorm 这几块串起来。

这篇会交付三样东西:论文核心段落的中英对照翻译、自注意力机制的最小 PyTorch 实现、以及用统一 Key 调用模型复现论文里英德/英法翻译示例的验证步骤。读完之后你应该能对着 Figure 1 说出每一层在干什么,也能自己写出一段能跑通的 MultiHeadAttention。

2. TaoToken 前置准备:统一 Key 调用模型复现论文翻译示例

论文第 6 节给了 WMT 2014 英德 28.4 BLEU、英法 41.8 BLEU 的结果,我们没法在本地复现完整训练,但可以用现成的大模型 API 来验证「注意力机制学到的翻译能力」这件事——把论文里的翻译示例喂进去,看模型输出是否符合预期。这里用 TaoToken 做统一入口,好处是一个 Key 能调多个模型,方便对照不同模型对同一句英文的翻译差异。

TaoToken 是一个模型 API 聚合平台,官网在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 端点是 https://taotoken.net/api 。它的定位是给开发者提供统一的调用方式,你不需要为每个模型单独申请账号、记不同的 Base URL。对于这篇论文精读的场景,我们主要用它来做两件事:一是调用对话模型验证翻译示例,二是如果你要长期跑 Agent 或编码任务,可以用 Coding Plan。

先拿到 Key。进入控制台创建 API Key,地址是 https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。创建后复制保存,后面配置里会用到。模型对话的入口在 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite ,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

这里要强调一个概念:论文里的 Transformer 是架构,TaoToken 提供的是已经训练好的大模型服务,两者不是一回事。我们用后者来「观察」前者学到的能力,比如把论文 6.1 节的翻译任务用现成模型跑一遍,看注意力机制在真实模型上的表现。如果你要写代码调用,Base URL 填 https://taotoken.net/api ,Key 填刚才创建的,Model ID 按文档里列出的填。这三件套(Base URL + Key + Model ID)是后面所有配置的基础,缺一不可。

3. 可复制配置:settings.json 与 PyTorch 自注意力最小实现

这一节给两块可直接复制的配置。第一块是调用模型验证翻译的客户端配置,第二块是论文 3.2.1 节 Scaled Dot-Product Attention 的 PyTorch 实现。

先看客户端配置。如果你用支持 OpenAI 兼容接口的工具,配置文件里这样写。以常见的 settings.json 形式为例:

{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的TaoToken密钥", "model": "按文档填写的Model ID", "temperature": 0.2, "max_tokens": 512 }

注意 base_url 不要带 UTM 参数,API 端点就是 https://taotoken.net/api 。model 字段去模型对话页面对照当前可用的 ID 填。temperature 设低一点,翻译任务要稳定输出。

再看论文核心公式的代码。Scaled Dot-Product Attention 的公式是 Attention(Q,K,V) = softmax(QK^T / sqrt(dk))V。用 PyTorch 写出来是这样:

import torch import torch.nn as nn import math class ScaledDotProductAttention(nn.Module): def __init__(self, d_k): super().__init__() self.d_k = d_k def forward(self, Q, K, V, mask=None): # Q: (batch, heads, seq_q, d_k) # K: (batch, heads, seq_k, d_k) # V: (batch, heads, seq_k, d_v) scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k) if mask is not None: scores = scores.masked_fill(mask == 0, -1e9) attn = torch.softmax(scores, dim=-1) output = torch.matmul(attn, V) return output, attn

这段对应论文 3.2.1 节。除以 sqrt(d_k) 的原因论文解释得很清楚:当 d_k 较大时,点积结果会变得很大,softmax 会进入梯度极小的区域,缩放是为了把数值拉回合理范围。你可以把 math.sqrt(self.d_k) 去掉跑一次,观察 softmax 输出的分布会变得多尖锐。

接着是论文 3.2.2 节的多头注意力。核心是把 d_model 拆成 h 个头,每个头维度 d_k = d_v = d_model / h = 64:

class MultiHeadAttention(nn.Module): def __init__(self, d_model=512, h=8): super().__init__() self.d_model = d_model self.h = h self.d_k = d_model // h self.d_v = d_model // h self.W_q = nn.Linear(d_model, d_model) self.W_k = nn.Linear(d_model, d_model) self.W_v = nn.Linear(d_model, d_model) self.W_o = nn.Linear(d_model, d_model) self.attention = ScaledDotProductAttention(self.d_k) def forward(self, Q, K, V, mask=None): batch = Q.size(0) # 线性投影后拆头 q = self.W_q(Q).view(batch, -1, self.h, self.d_k).transpose(1, 2) k = self.W_k(K).view(batch, -1, self.h, self.d_k).transpose(1, 2) v = self.W_v(V).view(batch, -1, self.h, self.d_v).transpose(1, 2) out, attn = self.attention(q, k, v, mask) # 拼头后过输出投影 out = out.transpose(1, 2).contiguous().view(batch, -1, self.d_model) return self.W_o(out), attn

论文里 h=8、d_model=512,所以每个头 64 维。多头的作用是让模型在不同表示子空间里并行关注不同位置的信息,单一头做平均会把这个能力压掉。你可以把 h 改成 1 跑一次,对比注意力的多样性。

位置编码对应论文 3.5 节,用正弦余弦函数:

class PositionalEncoding(nn.Module): def __init__(self, d_model, max_len=5000): super().__init__() pe = torch.zeros(max_len, d_model) position = torch.arange(0, max_len).unsqueeze(1).float() div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) self.register_buffer('pe', pe.unsqueeze(0)) def forward(self, x): return x + self.pe[:, :x.size(1)]

这三段拼起来就是一个最小可跑的注意力模块。论文 3.1 节说编码器堆 6 层、每层两个子层(多头自注意力 + 前馈网络),解码器多一个交叉注意力子层,你可以用上面的 MultiHeadAttention 加 nn.Linear 和 ReLU 把 FFN 补上,堆 6 层就是论文的 encoder。

4. 验证请求:用模型复现论文翻译示例并检查注意力输出

配置写好后要验证两件事:一是 API 能正常返回翻译结果,二是本地注意力代码的输出形状和数值合理。

先验证 API。用 curl 发一个请求,把论文摘要里的一句英文翻译成中文:

curl https://taotoken.net/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-你的TaoToken密钥" \ -d '{ "model": "按文档填写的Model ID", "messages": [ {"role": "user", "content": "Translate to Chinese: The dominant sequence transduction models are based on complex recurrent or convolutional neural networks."} ], "temperature": 0.2 }'

预期返回里 choices[0].message.content 应该是「主流的序列转换模型基于复杂的递归或卷积神经网络」这类译文。如果返回 401,说明 Key 不对;如果返回 model not found,说明 Model ID 填错了,去模型对话页面核对。

再验证本地注意力代码。构造一个 batch=2、seq_len=4、d_model=512 的输入,跑一遍多头注意力:

mha = MultiHeadAttention(d_model=512, h=8) x = torch.randn(2, 4, 512) out, attn = mha(x, x, x) print(out.shape) # 期望 torch.Size([2, 4, 512]) print(attn.shape) # 期望 torch.Size([2, 8, 4, 4])

attn 的形状是 (batch, heads, seq_q, seq_k),每个头的注意力权重在最后一维上求和应该接近 1(softmax 的性质)。你可以打印 attn[0, 0] 看第一个头的注意力分布,再打印 attn[0, 1] 看第二个头,正常情况下不同头的分布是不一样的,这正是论文 3.2.2 节说的「不同表示子空间」。

如果你想更贴近论文 6.1 节的翻译任务,可以把论文里的示例句子批量喂给 API,对比不同模型对同一句的翻译。论文报告英德 28.4 BLEU,我们用现成模型没法算 BLEU,但可以人工看译文质量。把结果整理成表格对照:

英文原句模型译文论文参考译文
The Transformer is the first transduction model relying entirely on self-attention.待填Transformer 是第一个完全依赖自注意力的转换模型
Multi-head attention allows the model to jointly attend to information from different representation subspaces.待填多头注意力使模型能够联合关注来自不同表示子空间的信息

这样跑一遍,你对论文 3.2 节和 6.1 节的理解会比纯读文字深很多。

5. 本篇常见错排查:401、local proxy failed 与 reading choices 报错

配置和验证过程中最容易踩的坑集中在几类报错上,逐个说清楚。

第一类是 401 Unauthorized。返回体里通常是 {"error": {"message": "Invalid API key"}}。原因有三个:Key 复制时带了空格、Key 已经失效、Authorization 头格式写错。正确格式是 Bearer sk-xxx,Bearer 和 Key 之间一个空格。去 API Keys 页面重新生成一个,粘贴时注意别把换行符带进去。

第二类是 local proxy failed 或 connection refused。这类报错说明请求根本没发到 https://taotoken.net/api ,而是被本地某个代理配置拦截了。检查你的环境变量里有没有 HTTP_PROXY、HTTPS_PROXY,或者工具配置里有没有指向本地的代理地址。把代理关掉,让请求直连 API 端点。注意 base_url 只写到 /api,不要自己拼 /v1 之外的路径。

第三类是 reading choices 相关报错,比如 KeyError: 'choices' 或 reading 'choices' failed。这通常发生在你解析响应时,返回体结构和你预期的不一样。先打印完整响应看结构,正常返回是 {"choices": [{"message": {"content": "..."}}]}。如果返回的是错误对象,里面没有 choices 字段,直接取就会报 KeyError。加一层判断:

resp = response.json() if "choices" not in resp: print("请求失败:", resp) else: print(resp["choices"][0]["message"]["content"])

第四类是 OAuth 或 token 过期相关。如果你用的是某些客户端工具,它可能走 OAuth 流程而不是直接填 Key。这种情况下确认工具是否支持自定义 Base URL,把 https://taotoken.net/api 填进去,认证方式选 API Key 而不是 OAuth。如果工具强制走 OAuth,换用支持 API Key 的客户端。

第五类是模型返回空内容或截断。检查 max_tokens 是不是设太小,翻译长句时 512 可能不够,调到 1024。另外 temperature 太高会导致输出不稳定,翻译任务建议 0.2 以下。

第六类是本地 PyTorch 代码报维度错误。最常见的是 view 之前没做 contiguous,或者 transpose 后直接 view。记住顺序:transpose 之后要 .contiguous().view(...)。还有 mask 的维度要对齐 (batch, 1, seq_q, seq_k) 或能广播的形状,否则 masked_fill 会报错。

6. 继续深入:从论文公式到工程实践的下一步

把上面的代码跑通之后,你已经走完了论文最核心的 3.2 节。接下来可以往几个方向深入。一是把完整的 encoder-decoder 堆起来,按论文 3.1 节堆 6 层,加上残差连接和 LayerNorm,跑一个简单的序列复制任务看能不能收敛。二是读论文 4 节「为什么选择自注意力」,里面比较了自注意力、循环层、卷积层的计算复杂度和最大路径长度,这部分对理解 Transformer 为什么快很关键。三是看论文 5 节的训练细节,Adam 优化器的 beta 参数、warmup_steps=4000 的学习率调度、dropout=0.1 和标签平滑 0.1,这些在工程实现里都会用到。

如果你要长期做编码或 Agent 任务,可以了解 Coding Plan,地址是 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有完整的参数说明和示例。模型对话入口在 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite ,可以对照不同模型对同一段论文的翻译和理解差异。

论文里还有几个值得动手的点:3.4 节的嵌入权重共享(embedding 和 pre-softmax 线性层共享权重矩阵)、3.5 节位置编码为什么选正弦而不是学习式、6.2 节的模型变种实验(改头数、改 d_k、加 dropout 对 BLEU 的影响)。每一个都可以用上面的代码框架改几行跑一遍,比只看表格印象深得多。Attention Is All You Need 这篇论文的价值不在于它多难,而在于它把复杂的东西做简单了,读的时候抓住「注意力是唯一的连接方式」这条主线,剩下的都是工程细节。

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

专利撰写实战:权利要求书、说明书规范与避坑指南

1. 专利写作到底在写什么:先分清三类文本的角色很多人第一次接触专利撰写,脑子里只有一个模糊印象——"把技术方案写下来,写得详细一点就行"。真正上手才发现,同一份申请文件里塞了三四种文本,每种文本的读者…

作者头像 李华
网站建设 2026/10/1 14:42:57

聚束模式成像与两步聚光:从仿真到精聚焦的工程实践

简介:这份资源围绕聚束模式成像(spotlight)展开,面向从事雷达、超声波或光学成像算法研究的工程师与研究生,尤其适合需要理解两步聚焦策略与MATLAB实现的读者。压缩包共3个文件,均为.m脚本,整体…

作者头像 李华
网站建设 2026/10/1 14:42:37

OpenHarmony I2C驱动开发实战:设备树配置、HDI接口与排障指南

1. 从一根线说起:I2C 在 OpenHarmony 里到底扮演什么角色搞 OpenHarmony 设备开发的朋友,绕不开的一个话题就是外设接入。你拿到一块 RK3568 或者 Hi3861 的开发板,想把温湿度传感器、OLED 屏、EEPROM 这些玩意儿接上去,第一个撞上…

作者头像 李华
网站建设 2026/10/1 14:42:26

GLM Coding Plan 全量上线 GLM-5.3:TaoToken 统一 Key 接入与验证清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 14:42:20

从一张普通人脸到直播画面:视频美颜SDK经历了哪些处理?

在直播、视频社交、短视频等场景中,“美颜”通常被认为只是给视频增加一个滤镜。但从软件开发的角度来看,一套完整的视频美颜SDK实际上涉及视频采集、人脸检测、关键点定位、图像分割、纹理处理、几何变形以及实时渲染等多个环节。如果把摄像头输出的一帧…

作者头像 李华