version: 2559fc82 (2024-04-02 10:17:24)

LLM 简介

LLM,全称Large Language Model,即大语言模型。近些年,随着GPT3的诞生,人们发现给更大参数量的模型喂更多数据,可以让模型具备一定的智能,俗称力大砖飞。

如果你对LLM完全没有概念,你可以选择任意一个在线服务体验一下,感受LLM的魅力。下面是一些服务:

  1. ChatGPT 官方,需国外信用卡与手机号 / 外国镜像 / 国内镜像
  2. Claude 官方,需国外信用卡与手机号
  3. Google Gemini 官方,需要Google账号

P.S. 使用镜像时请注意数据安全

LLM 是怎么训练的

在开始介绍之前,我们假设LLM是一个黑盒,即 output_text = LLM(input_text)。 从你的使用体验来说,你可以认为是 answer = LLM(question)。

那LLM是怎么训练出来的呢,其实是一个多阶段的过程。 首先,我们有海量的文本,比如网页、书籍、小说、百科等等,我们也有一些问答数据集,但是数量相比前者少很多,那么怎么同时用上这两种数据呢?

第一阶段,我们使用那些海量文本来训练续写任务,即在有raw_text的情况下,有

input_text = raw_text.drop(index=raw_text.length - 1)
output_text = raw_text.drop(index=0)

然后基于这样的数据去训练。这个过程被称为Pretraining,这样训练得出的模型称为Base model,只有续写能力,无法进行对话。

第二阶段,使用那些问答数据集,他们天然的就是满足上面的数据格式的,因此可以做训练。这个过程被称为Finetuning,训练完成后就是Chat Model对话模型了。

一般来说,有这两个阶段就可以产生一个可以进行对话的模型了,当然那些对话模型为了更好的用户体验,和回答的安全性,还做了对齐训练,这个在这里就不多介绍了。

LLM 是怎么工作的

LLM是一个神经网络,现在主流的大模型一般都是 Decoder-only 的 Transformer。这里我们不具体介绍这两个概念,把Transformer当个黑盒,你可以理解成这样 next_word_probs = Transformer(input_text)。 即他会在给定输入的情况下,输出下一个词的概率,而通过一系列的采样策略,我们可以根据概率来选择合适的词,即 next_word = Sampler(next_word_probs)。

整个流程大概如下:


i = 1
loop
    next_word_probs = Transformer(input_text)
    next_word = Sampler(next_word_probs)
    input_text += next_word
until next_word == EOS
output_text = input_text

也就是我们不停的去预测下一个词,把他拼到输入上,直到遇到结束符EOS。

LLM 的数据是怎么表示的

上面为了简化,我们假设Transformer模型输入输出的基本单位是单词word,但是实际上我们并不是使用word,而是使用tokens。 什么是tokens,你可以理解成一个更加灵活的word,即他可以是一个word,也可以是多个word,也可以是word的碎片。

为什么不直接使用words呢,因为他有以下一些问题

  1. 特殊符号数量太多
  2. 词表外的新单词无法表示
  3. 有时压缩比太低

为了解决上述问题,我们会有一个分词器Tokenizer,有 tokens = Tokenizer.encode(text) 和 text = Tokenizer.decode(text)。

Tokenizer中会包含一些特殊符号,比如我们前面说的EOS,还有PAD,是为了把输入组成多条一样长度的数据时填充的内容,有些模型还会有BOS,就是输入开始时加入的固定token。

问答数据具体是怎么构造的

为了区别在训练Chat Model时区分原有的续写任务和新的对话任务,我们需要把问答数据以一种特殊的方式进行组装,组装后的文本被称为Prompt。而我们一般是基于模板Template来进行组装的。 比如对于下列对话 饭吃了么? 吃了。 那么我们可以把他拼成这样一个格式: 问题:饭吃了么 回答:吃了。 下面是一些主流模型的Prompt例子

  • <|im_start|>human\n{输入}<|im_end|><|im_start|>bot\n{输出}<|im_end|>
  • ### Human: {输入}\n### Assistant: {输出}<|im_end|>

Pretraining 和 Finetuning 有什么区别?

除了前面介绍了数据组装的不一样,还有一些地方有些许的不同:

  1. 对于过长的文本Pretraining会倾向于截断,而Finetuning则是更偏向于丢弃
  2. 对于Prompt的输入部分,Finetuning通常不计算loss

从用法上来说

  1. Pretraining需要海量数据,数据质量要求稍低,Finetuning要求较高质量的少量数据
  2. 对于大量新知识(如学习新语言、医学术语等等),一般Finetuning可能不够,需要Pretraining
  3. Pretraining的成本远高于Finetuning

如何定制自己的模型

这是一个比较大的问题,我们建议先试试ChatGPT/GPT-4之类的大模型能否大致在功能层面满足你的需求(不涉及风格、安全性和内部数据的情况下)。如果这类大模型都没法完成你的需求,那么用本地的开源模型应该也是做不了的。

OK, 我们假设他可以做,但是由于种种原因(价格贵、数据安全)我们不能使用这些闭源的大模型服务,那我们应该怎么办呢?

我们依次尝试以下的方法(代价从小到大)

  1. 如果我们有比较少的数据,而且这些数据有现有的接口可以提供,而且内容时常变动,那么我们可以使用RAG。

    什么是RAG? 即Retrieval-Augmented Generation,就是像搜索那样,先把用户的请求通过关键词搜索或者向量搜索在知识库中出关联的文档,然后我们将这些关联的文档作为输入和用户输入拼在一起喂给LLM,从而拿到输出。如果使用RAG,那么我们可以先不训练模型,可以先直接在训练好的Chat模型上进行尝试。如果效果不够好,那么也可以Finetuning一波。

  2. 如果我们有少量的数据,而且这些数据不会变动,那么我们可以做Finetuning。

    数据量可以不用很多,几千到几万条即可,就是质量和多样性要保证。

  3. 如果我们有中等数量(十万到千万条)的数据,那么可以直接从Base Model进行训练。

  4. 如果你有大量数据(亿条数据),那么可以做Continue Pretraining。

  5. 当然如果你有海量数据(千亿条),那么从零Pretraining吧。

ChatGPT等闭源模型和开源模型有什么区别

  1. ChatGPT/GPT4闭源,数据安全无法保证
  2. 闭源模型效果一般优于开源模型
  3. 较小的开源模型可以本地部署,自己训练

如何搞数据

首先当然是使用公开的数据集了,有各种各样的数据集,可以在Huggingface Datasets中搜索。 这里也推荐几个质量较高的Finetuning数据集

  1. RoleLLM 角色扮演数据集,中英文
  2. CharacterLLM 复旦的角色扮演数据集,英语

如果从Base模型开始训练可以使用下面的数据

  1. MOSS 复旦NLP搞的中文多轮对话数据集
  2. UltraChat 清华的多轮对话数据集,英语

当然只有公开数据可能不能满足定制化的需求的,所以你手头上需要有一批自己的数据。

  1. 如果是高质量的问答数据,而且数量够多,OK我们可以直接开始训练了
  2. 如果只有原始数据,可以用ChatGPT/GPT-4之类的大模型来构造问答对。
  3. 如果数据量不够,一方面可以用ChatGPT/GPT-4之类的大模型来扩充,或者就是各种方法来搜刮数据(爬虫、解包、ASR转译、人肉标注等等)

从Chat模型训练和Base模型训练有什么区别

  1. Chat模型做过对话训练,因此可以不需要公开的通用语料。只用特定任务的语料即可。
  2. Chat模型有特定的Prompt模板,需要用那个模板组装数据。而Base模型,你可以任意选择Prompt模板。
  3. Chat模型一般都做过对齐训练,所以如果需要训练一些(你懂得)的内容的时候,你需要从Base模型开始训练。
  4. 从Base模型训练需要添加通用数据,而且需要一定数据量的数据。一般我们会做两阶段的Finetuning,通用指令Finetuning(IFT)以及特定任务微调(SFT)。

我该选择什么开源模型

选择标准

  1. 首先需要看你的显卡是否是老黄(Nvidia)家的?有多少显存(可以通过nvidia-smi查看)?这决定了你可以使用什么参数量级的模型。一般而言,如果是3090/4090, 那么你有24GB的显存,你可以最多微调13-14B左右的模型。如果是3080, 那只有10GB显存,最多能微调6-7B左右的模型。另外不建议使用旧于10系的显卡。

    14B中的B是什么意思?其实是模型参数量,Billon,即十亿参数。一般大公司内部小团队会使用6-14B左右的模型,再小的模型基本上就无法很好的完成多轮对话了,只能做点较为简单的小任务。

  2. 决定了参数量范围后,我们可以开始找模型

    a. 现在最火的国外模型是Mistral-7B(Base模型),Zephyr-7B(Chat模型)以及Google最近发布的Gemma-7B。

    b. 如果需要中文模型,那么有Qwen、Baichuan、InternLM、ChatGLM等很多选择,从我们的使用体验来说,Qwen的体验是比较好的,而且他支持多语言词表,可以提供一定的多语种能力。

    c. 可以在Huggingface Models搜索公开的模型

总结

这一章节我们大致介绍了LLM的一些基本概念和玩法。我们可以先挑选模型和收集数据,准备好之后我们就可以正式开始炼丹了。