NLP

0. 引言

您是否厌倦了人类之间使用离散语言的低效交流?您是否希望学习更加抽象且高效的表达方式,或者渴望与计算机建立更加连续的沟通?本门课程将从自然语言中单词的最基本表示——词向量开始讲起,详细讲解当前 $ NLP$ ( NaturalLanguageProcessingNatural Language Processing, 自然语言处理) 的主流模型 TransformerTransformer,并教授如何使用目前最热门的 NLPNLP 模型托管平台 HuggingFaceHugging Face 🤗。

如果您觉得自己的语言表达过于离散,希望学习具有连续性的表达方式;或者认为自己的表达过于直白,缺乏高层次的抽象;或者希望在本地部署类 ChatGPTChatGPT 语言模型,那么请将本课程压入您的运行栈。本课程虽无益于提升您作为人的表达能力,即教会您个人使用词向量表达并对高层次抽象语义特征进行提取,但可以使您的模型具有更加完备的自然语言理解与自然语言生成能力,从而在语言类任务中实现对您的代替。 在本课程中,您(或者您的模型,如果比您更智能的话)可以: 学习变形金刚的基本原理、结构,亲手组装并运行您的第一个变形金刚(模块无需自备)。了解大规模预训练语言模型的预训练、微调方法。 熟练掌握抱抱脸的使用场景与技巧。 对预训练语言模型进行微调,完成简单的文本任务。在学习完计算机视觉课程后,尝试使用多模态模型完成文本 & 图像任务。

1. 如何表示一个词的含义?

  • 用一个 idid 表示一个词?
  • 离散的 idid 型词语如何输入到神经网络之中?
  • 神经网络的输入对象通常是 featurefeature -> 我们需要得到词的 featurefeaturexw xw

🤗Word Embedding 词嵌入

  • 将一个词映射为一个 𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔  dim𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔 \; dim 维的向量
  • 每一维具有一定的含义(具体含义可能很抽象)

🤗如何获取 Word Embedding ?

  • 手工构造?

    • “北京在北纬 4040 度,所以必须有一维向量的值是 4040 ”?

  • 通过在任务中拟合数据获得

    • 例如对于 Next  token  predictionNext\;token\;prediction (根据前缀预测下个词)的任务:

    1. 随机初始化所有词 vvWord  EmbeddingWord\; Embedding EvE_v
    2. 将前缀的 EmbeddingEmbedding 求和取平均 Epredict=1kj=0k1EvjE_{\text{predict}} = \frac{1}{k} \sum_{j=0}^{k-1} E_{v_j}
    3. 下⼀个词是 EmbeddingEmbeddingEpredictE_{predict} 最接近的词 vpredict=maxvicos(Epredict,Evi)v_{\text{predict}} = \max_{v_i} \cos \left( E_{\text{predict}}, E_{v_i} \right)
    4. 计算 lossloss,反向传播

2. 如何获取词在句子中的向量表示?

An Apple a Day Keeps the Doctor Away

一天一部 Iphone 让我与博士学位失之交臂?

一个简单的想法:将句中所有词的向量加权求和,表示词在句中的含义。

🤗Skip-Gram & CBOW

一个词的意思取决于相邻词

🤗TextCNN

使用卷积来聚合特征

🤗RNN

预测下一个词

🤗长距离依赖?

🤗Attention is all you need!

🤗Attention Probs

  • 如何获取 𝑎𝑡𝑡𝑒𝑛𝑡𝑖𝑜𝑛  𝑝𝑟𝑜𝑏𝑠𝑎𝑡𝑡𝑒𝑛𝑡𝑖𝑜𝑛\;𝑝𝑟𝑜𝑏𝑠?两个词越相关越大?

  • 以两个词 𝐸𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔𝐸𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔 的余弦夹角表示相似度:

attention scores(vi,vj)=cos(Evi,Evj)\text{attention scores}(v_i, v_j) = \cos \left( E_{v_i}, E_{v_j} \right)
  • 使用 𝑆𝑜𝑓𝑡𝑚𝑎𝑥𝑆𝑜𝑓𝑡𝑚𝑎𝑥 归一化:
attention probs(vi,vj)=eattention scores(vi,vj)k=0sequence lengtheattention scores(vi,vk)\text{attention probs}(v_i, v_j) = \frac{e^{\text{attention scores}(v_i, v_j)}}{\sum_{k=0}^{\text{sequence length}} e^{\text{attention scores}(v_i, v_k)}} Eviin  sentence=j=0seq  lenattention probs(vi,vj)EjE_{v_iin\;sentence}= \sum_{j=0}^{\text{seq\;len}} \text{attention probs}(v_i, v_j) E_j

🤗如何科学获取Attention Score?

  • 𝐸𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔𝐸𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔 的余弦夹角:与 𝑣i𝑣_{i} 相似的特征真的是 𝑣i𝑣_{i} 需要的吗?🤔

    • 假如句子为:🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎are good.

    •与 𝐸🍎𝐸_{🍎} 最接近的总是 𝐸🍎𝐸_{🍎}𝐸🍎in  sentence𝐸_{🍎in\;sentence}= 𝐸🍎𝐸_{🍎}

  • 𝐸𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔(𝑄𝑢𝑒𝑟𝑦,𝐾𝑒𝑦)𝐸𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔 → (𝑄𝑢𝑒𝑟𝑦,𝐾𝑒𝑦) 🤗🤗🤗

  • 𝑄𝑢𝑒𝑟𝑦𝑄𝑢𝑒𝑟𝑦:想查询的特征

  • 𝐾𝑒𝑦𝐾𝑒𝑦:想被查询的特征

attention scores(vi,vj)=cos(Evi,Evj)\text{attention scores}(v_i, v_j) = \cos \left( E_{v_i}, E_{v_j} \right)

🤔 Attention

EmbeddingLinear(Query, Key, Value)\text{Embedding}\xrightarrow{\text{Linear}} (\text{Query, Key, Value}) attention scores(vi,vj)=cos(Evi,Evj)\text{attention scores}(v_i, v_j) = \cos \left( E_{v_i}, E_{v_j} \right) attention probs(vi,vj)=eattention scores(vi,vj)k=0sequence lengtheattention scores(vi,vk)\text{attention probs}(v_i, v_j) = \frac{e^{\text{attention scores}(v_i, v_j)}}{\sum_{k=0}^{\text{sequence length}} e^{\text{attention scores}(v_i, v_k)}} Vviinsentence=j=0seq lenattention probs(vi,vj)VjV_{v_iin sentence} = \sum_{j=0}^{\text{seq len}} \text{attention probs}(v_i, v_j) V_j EviinsentenceLinearVviinsentenceE_{v_iin sentence} \xleftarrow{\text{Linear}} V_{v_iin sentence}

🤗 Attention

  • QueryQuery: 我想找到他的名字…

  • KeyKey:

    • 小明 * 他的名字 = 0.8

    • 他 * 他的名字 = 0.1

    • 小博物学家 * 他的名字 = 0.05

    • …

  • ResultResult = 0.8 * V小明V_{小明} + 0.1 * VV_{他} + 0.05 * V小博物学家V_{小博物学家} + …

🤗 Attention

  • Input: Embeddingsshape=(seq len,embedding dim)\text{Input: } \text{Embeddings}_{\quad \text{shape} = (\text{seq len}, \text{embedding dim})}

  • Q=Qproj(Embeddings)shape=(seq len,query dim)Q = Q_{\text{proj}}(\text{Embeddings})_{\quad \text{shape} = (\text{seq len}, \text{query dim})}

  • K=Kproj(Embeddings)shape=(seq len,key dim),  key dim=query dimK = K_{\text{proj}}(\text{Embeddings}) _{\quad \text{shape} = (\text{seq len}, \text{key dim}), \; \text{key dim} = \text{query dim}}

  • V=Vproj(Embeddings)shape=(seq len,value dim)V = V_{\text{proj}}(\text{Embeddings}) _{\quad \text{shape} = (\text{seq len}, \text{value dim}) }

  • Attention Probs(Q,K)=softmax(QKTd)shape=(seq len,seq len)\text{Attention Probs}(Q, K) = \text{softmax}\left(\frac{QK^T}{\sqrt{\text{d}}}\right) _{\quad \text{shape} = (\text{seq len}, \text{seq len})}

  • Attention(Q,K,V)=softmax(QKTd)Vshape=(seq len,value dim)\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{\text{d}}}\right) V _{\quad \text{shape} = (\text{seq len}, \text{value dim}) }\\

  • Output=Oproj(Attention(Q,K,V))shape=(seq len,embedding dim)\text{Output} = O_{\text{proj}}(\text{Attention}(Q, K, V)) _{\quad \text{shape} = (\text{seq len}, \text{embedding dim})}

🤗如何加入位置信息🧭?

  • AttentionAttention 机制中,并没有考虑向量在 sequencesequence​ 中的位置。

  • 𝑃𝑜𝑠𝑖𝑡𝑖𝑜𝑛𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔𝑃𝑜𝑠𝑖𝑡𝑖𝑜𝑛 𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔:为每一个位置预设一个向量 𝑃𝐸pos𝑃𝐸_{pos}

Eviinput=Evi+PEposE_{v_iinput} = E_{v_i} + PE_{pos}

3. 如何在模型中存储知识?

🤗模型中知识存在何处?

  • 知识:KeyValuePair:(K,V)Key-Value Pair: (K, V)

  • NeuralMemoryNeural Memory,使用 xx 查询 kik_i

p(kix)ekixp(k_i|x) \propto e^{k_i x} MN(x)=i=1dimp(kix)viMN(x) = \sum_{i=1}^{\text{dim}} p(k_i|x) \cdot v_i K=[ki],V=[vi]K = [k_i], V = [v_i] MN(x)=softmax(xKT)VMN(x) = \text{softmax}(xK^T)V
  • 用两个线性层实现前馈神经网络:
FFN(x)=f(xKT)VFFN(x) = f(xK^T)V

🤗 Feedforward Neural Network

FFN(x)=f(xKT)VFFN(x) = f(xK^T)V
  • 𝑓𝑓 一般使用 𝑟𝑒𝑙𝑢𝑟𝑒𝑙𝑢 或其变种
  • 一般 inner  h𝑖𝑑𝑑𝑒𝑛  diminner\;ℎ𝑖𝑑𝑑𝑒𝑛 \;dim = 4  𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔  dim4\;𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔\;dim
  • 参数量:8×𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔𝑠  dim28×𝑒𝑚𝑏𝑒𝑑𝑑𝑖𝑛𝑔𝑠\;dim^2

🤗 Transformer

  • InputInput 序列到 OutputOutput 序列——Seq2SeqSeq2Seq

4. 如何基于以上原理构建语言模型?

  • 语言模型:Pθ(w|context)P_\theta (\text{w|context})

  • 𝑐𝑜𝑛𝑡𝑒𝑥𝑡𝑐𝑜𝑛𝑡𝑒𝑥𝑡:上下文

  • ww:某个位置上的某个词的概率

  • 自编码语言模型(如 BERTBERT):

    • “北京在北纬[MASK][MASK]度”,求[MASK][MASK]填词的概率分布:𝑃(•|北京在北纬[MASK][MASK]度)

  • 自编码语言模型(如 GPTGPT):

    • “北京在北”,求下一个字的概率分布:𝑃(•|北京在北)

🤗 Encoder Only

  • InputInput 序列到分类输出—— ClassificationClassification
  • 典型模型:BERTBERT

🤗 Decoder Only

  • 从输入序列到输入序列的延长—— GenerationGeneration
  • 典型模型:GPTGPT

🤗 Attention Types

  • SelfAttentionSelf Attention: QKVQKV 来自同一序列
  • CrossAttentionCross Attention: QKVQKV 来自不同序列

  • 一种特殊的 SelfAttentionSelf Attention

🤗 Multi Head Attention 🙂🙂🙂

  •  (Q0,Q1,Q2,Q3)=Q=Qproj(Embeddings)Qi. shape=(seq len,embeddings dimnum head)\ (Q_0, Q_1, Q_2, Q_3) = Q = Q_{\text{proj}}(\text{Embeddings}) \quad Q_i.\ \text{shape} = (\text{seq len}, \frac{\text{embeddings dim}}{\text{num head}}) \\

  •  (K0,K1,K2,K3)=K=Kproj(Embeddings)Ki. shape=(seq len,embeddings dimnum head)\ (K_0, K_1, K_2, K_3) = K = K_{\text{proj}}(\text{Embeddings}) \quad K_i.\ \text{shape} = (\text{seq len}, \frac{\text{embeddings dim}}{\text{num head}})

  •  (V0,V1,V2,V3)=V=Vproj(Embeddings)Vi. shape=(seq len,embeddings dimnum head)\ (V_0, V_1, V_2, V_3) = V = V_{\text{proj}}(\text{Embeddings}) \quad V_i.\ \text{shape} = (\text{seq len}, \frac{\text{embeddings dim}}{\text{num head}})

  • Output=Oproj(Concat(Attention(Qi,Ki,Vi)))\text{Output} = O_{\text{proj}}(\text{Concat}(\text{Attention}(Q_i, K_i, V_i)))

  • 参数量: 4×embeddings dim2\ 4 \times \text{embeddings dim}^2

  • 不同 HeadHead 关注不同的语义关系

🤗 Group Query Attention

🤗 Transformer

  • LMHeadLM Head:一个线性层,输入维度为 embeddingdimembedding dim;输出维度为词表大小 vocab  sizevocab\;size
  • 输出每个位置上各词未归一化的对数概率 logits:
Pθ(context)=softmax(logits)P_\theta (\cdot \mid \text{context}) = \text{softmax}(\text{logits})
  • 左侧为 EncoderEncoder
  • 右侧为 DecoderDecoder

🤗 Encoder

  • BERTBERT
  • 一次前向传播即可计算出所有[MASK][MASK]的概率分布
  • 文本理解任务

🤗 Decoder

  • GPTGPT
  • 自回归生成:每次生成下一个词
  • MaskedAttentionMasked Attention:每个词做AttentionAttention时只能加权到之前的词
  • 文本生成任务

🤗如何训练语言模型?

  • 随机初始化权重𝜃

  • 反复随机初始化权重𝜃,直到权重能较好地完成任务❌

  • 使用大量人工标注文本对模型进行训练😧😧😧

  • 使用大量无标注文本对模型进行训练🧐😉🤗

🤗预训练

  • MaskfillingorNexttokenprediction?Mask filling or Next token prediction?

  • MaskfillingMask filling:

    • 我是[MASK][MASK][MASK][MASK]考试没有一次[MASK][MASK]

maxθ(Pθ(大学生|context)Pθ(幼儿园|contextPθ(参加|context))\max_\theta \left( P_\theta (\text{大学生|context}) \cdot P_\theta (\text{幼儿园|context} \cdot P_\theta (\text{参加|context}) \right)
  • NexttokenpredictionNext token prediction:

    • 我是大学生,

maxθ(Pθ(next tokenprefix))=maxθ(Pθ(大学生|我是)Pθ(, |我是大学生))\max_\theta \left( \prod P_\theta (\text{next token} \mid \text{prefix}) \right) = \max_\theta \left( P_\theta (\text{大学生|我是}) \cdot P_\theta (\text{, |我是大学生}) \right)

🤗如何使用语言模型完成具体下游任务?

  • 反复随机初始化权重𝜃,直到权重𝜃能较好地完成任务❌
  • 在预训练模型的基础上继续使用大量无标注文本训练😟
  • 使用少量标注数据 (𝑥,𝑦)(𝑥,𝑦) 模型进行训练🤗🤗🤗

例:分类任务

  • 替换预训练模型中的 LMHeadLM HeadClassificationHeadClassification Head

  • ClassificationHeadClassification Head 输入维度为 embeddingdimembedding\,dim

  • 输出维度为类别数目 numlabelsnum\,labels

  • 然后直接拿去部署

  • 使用标注的数据 (𝑥,𝑦)(𝑥,𝑦) 进行训练

    xx:文本;yy:类别

🤗如何使用有限的硬件资源进行微调?

  • LoRA:LowRankAdaptationLoRA: Low-Rank Adaptation

🤗如何让语言模型更好的理解人类意图?

  • 指令微调
  • 使用人工标注的 (prompt,responseprompt, response) 对模型进行微调
  • 强化学习