0.前置知识
分词(tokenize)
语言模型是对文本进行推理。由于文本是字符串,但对模型来说,输入只能是数字,所以就需要将文本转成用数字来表达。构造一个字典,包含文本中所有出现的词汇,比如中文,可以每个字作为词典的一个元素,构成一个列表;一个句子就可以转换成由每个词的编号(词在词典中的序号)组成的数字表达。
tokenize就是分词,一般分成3种粒度:
word(词)
词是最简单的方式,例如英文可以按单词切分。缺点就是词汇表要包含所有词,词汇表比较大;还有比如“have”,"had"其实是有关系的,直接分词没有体现二者的关系;且容易产生oov问题(Out-Of-Vocabulary,出现没有见过的词)
char(字符)
用基础字符表示,比如英文用26个字母表示。比如 "China"拆分为"C","h","i","n","a",这样降低了内存和复杂度,但增加了任务的复杂度,一个字母没有任何语义意义,单纯使用字符可能导致模型性能的下降。
subword(子词)
结合上述2个的优缺点,遵循“尽量不分解常用词,将不常用词分解为常用的子词”的原则。例如"unbelievable"在英文中是un+形容词的组合,表否定的意思,可以分解成un”+"believable"。通过这种形式,词汇量很大,也能保留词的关系,同时还能缓解oov问题。
subword分词主要有BPE,WorkdPiece,Unigram等方法。
BPE:字节对编码,就是是从字母开始,不断在语料库中找词频最高、且连续的token合并,直到达到目标词数。
WordPiece:WordPiece算法和BPE类似,区别在于WordPiece是基于概率生成新的subword而不是下一最高频字节对。
Unigram:它和 BPE 等一个不同就是,bpe是初始化一个小词表,然后一个个增加到限定的词汇量,而 Unigram 是先初始一个大词表,接着通过语言模型评估不断减少词表,直到限定词汇量。
参考链接
Suprit:BPE 算法原理及使用指南【深入浅出】
https://zhuanlan.zhihu.com/p/448147465
BPE、WordPiece和SentencePiece
https://www.jianshu.com/p/d4de091d1367
Luke:深入理解NLP Subword算法:BPE、WordPiece、ULM
https://zhuanlan.zhihu.com/p/86965595
现在已经有很多预训练好的词汇表,如果需要扩充新的语言,比如中文,可以先收集好语料库(训练文本),然后用SentencePiece训练自己的分词模型。
参考链接
使用sentencepiece中BPE训练中文词表,并在transformers中进行使用
https://github.com/taishan1994/sentencepiece_chinese_bpe
嵌入(embedding)
经过分词,文本就可以分解成用数字表示的token序列。对于一个句子,最直接的表示法就是one-hot编码。假如词汇表【我,喜,欢,吃 , 面】,此时词汇大小(vocab_size)大小为5,当词汇表特别大时(LLaMA词汇大小是3万多),句子的向量(n*vocab_size)表示也就变得比较大;另外,“喜欢”这个词出现在一起的频率其实比较高,但one-hot编码也忽略了这个特性。
# 一般embedding在语言模型的最开始,也就是词token操作之后# vocab_size 词汇表大小,hidden_size 隐藏层维度大小word_embeddings= nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)# input_ids是句子分词后词id,比如上述的“我喜欢”可转换成为[0,1,2],数字是在词汇表【我,喜,欢,吃, 面】中的索引,即token idembeddings = word_embeddings(input_ids) # embeddings的shape为[b,s,d],b:batch,s:seq_len,d:embedding size
embedding的每维特征都可以看出词的一个特征,比如人可以通过身高,体重,年龄等多个特征表示,对于每个词embedding的每个维度的具体含义,不用人为定义,模型自己去学习。这样,在d维空间上,语义相近的词的向量就比较相似了,同时embedding还能起到降维的作用,将one-hot的[s,vocab_size]大小变成了[s, d]。
参考链接
千寻:Embedding的作用
https://zhuanlan.zhihu.com/p/83814532
Transformer结构
Transformer由论文《Attention is All You Need》提出,现在是谷歌云TPU推荐的参考模型。论文相关的Tensorflow的代码可以从GitHub获取,其作为Tensor2Tensor包的一部分。哈佛的NLP团队也实现了一个基于PyTorch的版本,并注释该论文。

细节理论解释和实现可以参考网站https://nn.labml.ai/zh/

参考链接
Attention is All You Need
https://arxiv.org/abs/1706.03762
Transformer模型详解
https://zhuanlan.zhihu.com/p/338817680
多头注意力 (MHA)
https://nn.labml.ai/zh/transformers/mha.html
LLaMA2模型
LLaMA2是meta最新开源的语言大模型,训练数据集2万亿token,上下文长度是由LLaMA的2048扩展到4096,可以理解和生成更长的文本,包括7B、13B和70B三个模型,在各种基准集的测试上表现突出,最重要的是,该模型可用于研究和商业用途。
transformer可以分成2部分,encoder和decoder,而LLaMA只用了tranformer的decoder部分,是decoder-only结构。目前大部分生成式的语言模型都是采用这种结构,bert采用Encoder-only,google t5采用encoder-decoder结构。
LLaMA和LLaMA2在模型结构了基本一致,其中每个decoder层,主要是将transformer中的LayerNorm换成了RMSNorm,Multi-Head Attention换成了GQA(LLaMA是MQA),postionnal换成了RotatyEmbedding(RoPE相对位置编码)。
参考链接
为什么现在的LLM都是Decoder-only的架构? - 科学空间|Scientific Spaces
https://kexue.fm/archives/9529
Transformer升级之路:2、博采众长的旋转式位置编码 - 科学空间|Scientific Spaces
https://spaces.ac.cn/archives/8265
1.训练(training)
训练分为预训练、指令微调、奖励模型训练。
1.1 数据集(datasets)
公开的安全书籍,安全知识库,安全论文,安全社区文章,漏洞库等
https://huggingface.co/datasets/w8ay/security-paper-datasets
1.2 预训练(pre-training)
(1)扩充词表
用sentencepiece训练新的词表。
参考链接
GitHub - taishan1994/sentencepiece_chinese_bpe
https://github.com/taishan1994/sentencepiece_chinese_bpe
然后合并新的词表
参考链接
Chinese-LLaMA-Alpaca merge_tokenizers
https://github.com/ymcui/Chinese-LLaMA-Alpaca/blob/main/scripts/merge_tokenizer/merge_tokenizers.py
(2)预训练
主要参考2个库。
LLaMA-Efficient-Tuning:https://github.com/hiyouga/LLaMA-Efficient-Tuning,支持单GPU训练。
Chinese-LLaMA-Alpaca-2-预训练脚本:https://github.com/ymcui/Chinese-LLaMA-Alpaca-2/wiki/pt_scripts_zh,支持多级多卡训练。
Chinese-LLaMA-Alpaca-2支持的训练模式,根据相应情况传入model_name_or_path。本项目中LLaMA-2模型与Alpaca-2模型使用相同的tokenizer,不再进行区分。不支持未在表格中的模式。
1.2.1 训练后文件整理
LoRA模型无法单独使用,必须与Chinese-Alpaca-2-7B-16K进行合并才能转为完整模型。训练后的LoRA权重和配置存放于${output_dir}/pt_lora_model,通过以下方法对模型进行合并。
在线转换
https://github.com/ymcui/Chinese-LLaMA-Alpaca-2/wiki/online_conversion_zh,可利用本项目提供的notebook进行在线转换并量化模型。
手动转换
https://github.com/ymcui/Chinese-LLaMA-Alpaca-2/wiki/manual_conversion_zh,离线方式转换,生成不同格式的模型,以便进行量化或进一步精调。
1.3 监督微调(SFT,Supervised Fine-Tuning)
分为参数高效微调和全部/部分参数微调。
参数高效微调一般是冻结原模型,通过adapter、LoRA、Prefix-tuning(前缀微调)等方法微调,peft库目前已经支持这些方法,一般用LoRA,结构简单。
参考链接
大模型微调(finetune)方法总结-LoRA, Adapter, Prefix-tuning,P-tuning,Prompt-tuning
https://zhuanlan.zhihu.com/p/636481171
Chinese-LLaMA-Alpaca-2-指令精调脚本
https://github.com/ymcui/Chinese-LLaMA-Alpaca-2/wiki/sft_scripts_zh
1.4 人类反馈的强化学习微调(RLHF)
LLaMA2增加了RLHF(Reinforcement Learning from Human Feedback)基于人类反馈的强化学习。
(1)先对模型进行微调
(2)训练一个奖励模型
原则上,我们可以直接用人类标注来对模型做 RLHF 微调。然而,这将需要我们给人类发送一些样本,在每轮优化后计分,这个流程需要耗费大量人工,且需要大量数据集,而人类阅读和标注的速度有限。更简单的办法就是用人类标注集来训练一个奖励模型。
奖励模型的目的是模拟人类对文本的打分。
构建奖励模型有许多能用的策略: 最直接的便是预测标注 (比如根据好与坏,输出比分或者布尔值)。
最佳实践是,预测结果的排序,即对每个 prompt (输入文本) 对应的两个结果yk,yj,模型预测人类标注的比分哪个更高。
(3)基于人类反馈的强化学习
有了微调的语言模型和奖励模型,可以开始执行 RL 循环了,主要分为以下三步:
生成对 prompt (输入文本) 的反馈。
用奖励模型来对反馈评分。
对评分,进行一轮策略优化的强化学习。
trl-stack_LLaMA_2
https://github.com/huggingface/trl/tree/main/examples/research_projects/stack_LLaMA_2/scripts
StackLLaMA用 RLHF 训练 LLaMA 的手把手教程
https://github.com/huggingface/blog/blob/main/zh/stackLLaMA.md
LLaMA-Efficient-Tuning-奖励模型训练
https://github.com/hiyouga/LLaMA-Factory/blob/main/README_zh.md
1.5 长上下文版模型评测
LongBench是一个大模型长文本理解能力的评测基准,由6大类、20个不同的任务组成,多数任务的平均长度在5K-15K之间,共包含约4.75K条测试数据。
参考链接
LongBench推理代码
https://github.com/ymcui/Chinese-LLaMA-Alpaca-2/wiki/longbench_zh
LongBench
https://github.com/THUDM/LongBench
2.应用
2.1 模型部署、量化、推理
Chinese-LLaMA-Alpaca-2相关模型主要支持以下量化、推理和部署方式,具体内容请参考对应教程。

† 工具支持该特性,但教程中未实现,详细说明请参考对应官方文档
‡ 指是否支持长上下文版本模型(需要第三方库支持自定义RoPE)
§ vLLM后端不支持长上下文版本模型
参考链接
https://github.com/ggerganov/LLaMA.cpp
https://github.com/huggingface/transformers
https://colab.research.google.com/drive/1yu0eZ3a66by8Zqm883LLtRQrguBAb9MR?usp=sharing
https://platform.openai.com/docs/api-reference
https://github.com/oobabooga/text-generation-webui
https://github.com/hwchase17/langchain
https://github.com/imartinez/privateGPT
2.1.1 AWQ版模型
AWQ(Activation-aware Weight Quantization)是一种高效的模型量化方案,目前可兼容Transformers、LLaMA.cpp等主流框架。
本项目模型的AWQ预搜索结果:https://huggingface.co/hfl/chinese-LLaMA-alpaca-2-awq
生成AWQ量化模型(AWQ官方目录):https://github.com/mit-han-lab/llm-awq
LLaMA.cpp中使用AWQ:https://github.com/ggerganov/LLaMA.cpp/tree/master/awq-py
2.2 Ai-agent应用
将LLM作为大脑,ai agent可以做到根据任务目标,进行思考,分解任务,然后调用相应工具完成任务。
参考链接
ai agent应用技术介绍: https://zhuanlan.zhihu.com/p/662854606
AgentGPT原文blog: Autonomous AI in your browser: https://reworkd.ai/blog/Understanding-AgentGPT
agentgpt demo网址: https://agentgpt.reworkd.ai/zh
Plan-and-Solve-Prompting技术: https://github.com/AGI-Edgerunners/Plan-and-Solve-Prompting
Prompt Engineering Guide文档: https://www.promptingguide.ai/
Learn Prompting: Your Guide to Communicating with AI: https://learnprompting.org/docs/intro
Kevin:LangChain:一个让你的LLM变得更强大的开源框架: https://zhuanlan.zhihu.com/p/636043995
Memory | ️Langchain: https://python.langchain.com/docs/modules/memory/
开源ai-agents列表:awesome-ai-agents: https://github.com/e2b-dev/awesome-ai-agents
叶赛文:ChatGPT api里的system,user,assistant有什么作用?如何使用?: https://zhuanlan.zhihu.com/p/638552350
AutoGPT: https://github.com/Significant-Gravitas/AutoGPT
BabyAGI: https://github.com/yoheinakajima/babyagi
openagents: https://github.com/xlang-ai/openagents
langchain中文教程: https://github.com/liaokongVFX/LangChain-Chinese-Getting-Started-Guide
awesome-langchain: https://github.com/kyrolabs/awesome-langchain