今天我们聊聊大模型(LLM)中的一个看似“配角”却至关重要的主角——位置编码(Positional Encoding)。
你可能听过Transformer架构,GPT系列,LLM大模型……但有没有想过,Transformer虽然能处理文本,但它本身并不知道单词的顺序。这听起来是不是有点“离谱”?没错,要不是“位置编码”这个神奇的设计,Transformer就像看小说时不看章节顺序,一团糟。
那么问题来了:
别急,今天咱们一文带你搞懂!
传统的RNN、LSTM这种序列模型,天生是“线性串行”的。你给我第一个词,我处理完了,再处理第二个……信息一个接一个过来。
但是到了Transformer架构,一切都变了!
Transformer的多头自注意力机制(Multi-head Self-Attention)是并行处理所有输入token的。每个词之间的相对顺序,在它眼里根本“不存在”。这就导致一个严重问题:
“我”爱“你”和“你”爱“我”,在模型看来是一模一样的输入!
为了补上这块短板,位置编码就来了。
这是最经典的,也是最早被Transformer论文使用的方法。思想很简单:我们用一堆正弦函数和余弦函数来表示不同位置的信息。
公式如下:
import numpy as np
import torch
def get_sinusoidal_encoding(seq_len, d_model):
pos = np.arange(seq_len)[:, np.newaxis]
i = np.arange(d_model)[np.newaxis, :]
angle_rates = 1 / np.power(10000, (2 * (i // 2)) / np.float32(d_model))
angle_rads = pos * angle_rates
# Apply sin to even indices in the array; cos to odd indices
angle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2])
angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2])
return torch.tensor(angle_rads, dtype=torch.float32)
encoding = get_sinusoidal_encoding(10, 16)
print(encoding.shape) # torch.Size([10, 16])
这种方式的优点是:不需要训练参数,可以外推到任意长度。但缺点是:不一定适用于非常复杂的上下文结构。
后来的GPT系列采用了另一种方式:每一个位置都分配一个可训练的向量,直接加入输入token的embedding中。
import torch.nn as nn
class LearnablePositionalEncoding(nn.Module):
def __init__(self, max_len, d_model):
super().__init__()
self.pos_embedding = nn.Embedding(max_len, d_model)
def forward(self, x):
positions = torch.arange(x.size(1), device=x.device).unsqueeze(0)
return x + self.pos_embedding(positions)
这就像给每个位置“贴上标签”,模型训练过程中自己学出哪些位置重要。
你可以这样理解:
这样,模型就能“意识到”:
“哦,原来‘你’出现在第三个位置,它的作用和出现在第一个位置是不一样的。”
更形象点:就像我们听一句话,不仅听“是什么词”,还听“它出现在什么地方”。
我曾经做过一个简单的实验,分别在有位置编码和没有位置编码的Transformer上训练一个语言模型,句子是:
我 喜欢 吃 火锅
火锅 吃 喜欢 我
没有位置编码的模型,loss根本降不下去,因为它根本无法区分哪种顺序是“合理语法”。
有位置编码的模型,立马就能学到“我喜欢吃火锅”是更优的表达。
近几年大家发现:原始的位置编码有点“太死板”了。
于是各种进阶版登场:
这些方法的目的都是:在不增加太多复杂度的同时,更好地融合位置信息。
回到标题:为什么位置信息如此关键?
因为Transformer处理的是“包子铺排队”的输入,它并不知道谁先来、谁后到。位置编码就是给每个词贴上了“排队号”,让模型知道谁是谁,谁前谁后。
就像我们吃自助餐,排队先后顺序非常关键,要不然别人还没夹你就吃饱了!
很多刚入门LLM的朋友,眼里只有注意力、多头机制、残差结构,却忽略了位置编码这个“小齿轮”。但要知道,没有它,整个Transformer都转不起来。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。