type
status
date
slug
summary
tags
category
icon
password
Description
从一个最简单的模型开始,介绍大模型是如何工作的。
大模型是如何工作的
先来讲几个名词:
token:指文本数据的最小单位。在自然语言处理任务中,一个token可以是一个单词、一个字母、一个标点符号或者其他更小的文本单位;
context:上下文,指的是输入模型的文本序列。这个文本序列可以是一个句子、一个段落,甚至是更长的文本片段;
vocab_size:单个 token 有多少种可能的值,例如0和1两种;
context_length:上下文长度,用token个数来表示,例如 3 个 token。
开始吧。
用一个最简单的模型来讲,规定是:Token为
0 和 1 ,上下文长度为 3。那么,这个模型所有状态空间为
0, 1, 00, 01, 10, 11, 000, 001, 010, 011, 100, 101, 110, 111 一共14个,计算的方法为:2^1 + 2^2 + 2^3 = 14。简化一下,如果所有状态都是满的,即context_length 为3,那么一共的可能为:000, 001, 010, 011, 100, 101, 110, 111 一共8种,计算的方法为:vocab_size^context_length = 8 。 可以将模型想象成抛硬币:
- 正面朝上表示
token=1,反面朝上表示token=0;
- 新来一个
token时,将更新context:将新token追加到最右边,然后把最左边的token去掉,从而得到一个新context;
从旧的上下文(例如
010)到新的上下文(例如 101)为一次状态转移。初始状态下,我们输入一个数,下一个是0和1的概率是差不多的,状态转移图如下。

可以看到有如下几个特点:
- 在每个状态下,下一个
token只有0和1两种可能,因此每个节点有 2 个出向箭头;
- 每次状态转换时,最左边的
token被丢弃,新token会追加到最右侧;
- 此时的状态转移概率大部分都是均匀分布的,因为我们还没拿真正的输入序列来训练这个模型。
现在,我们使用这一串数字
111101111011110进行50次训练,训练完成后,状态转移图如下。
可以看到有如下几个特点:
- 在训练数据中,状态
101 -> 011的概率是 100%,因此我们看到训练之后的模型中,101 -> 011的转移概率很高;
- 在训练数据中,状态
111 -> 111和111 -> 110的概率分别是 50%; 在训练之后的模型中,两个转移概率分别为 45% 和 55%,也差不多是一半一半;
- 没有看到 100% 或 50% 的转移概率,这是因为没有经过充分训练,继续训练就会出现更接近这两个值的转移概率。
接下来开始测试训练后的模型,输入
111 后,输出11101110111011011110101 ,而我们之前训练的序列是111101111011110 ,我们的训练的越充分,采样得到的序列就会跟训练序列越像。 但在本文的例子中,我们永远得不到完美结果, 因为状态111的下一个token是模糊的:50% 概率是1,50% 是0。将这个例子放大无数倍(例如
GPT-2 ,它的vocab_size为50k ,context_length为2k )其实就是我们使用的大模型,当然整个过程要比这个复杂得多。如何训练一个语言大模型
先来讲几个名词:
SFT(Supervised Fine-Tuning):监督微调;
RLHF(Reinforcement Learning from Human Feedback):从人类反馈中进行强化学习。
开始。
首先进行的是收集大量的数据,即语料,以Meta/Facebook训练的LLaMA模型为例,它的数据集为下表。
数据集(Dataset) | 占比(Proportion) | 迭代次数(Epochs) | 数据集大小(Disk size) |
CommonCrawl | 67.0% | 1.10 | 3.3 TB |
C4 | 15.0% | 1.06 | 783 GB |
Github | 4.5% | 0.64 | 328 GB |
Wikipedia | 4.5% | 2.45 | 83 GB |
Books | 4.5% | 2.23 | 85 GB |
ArXiv | 2.5% | 1.06 | 92 GB |
StackExchange | 2.0% | 1.03 | 78 GB |
拿到数据后,会将内容进行预处理,即进行向量化,结合第一节中的知识,即将内容变成一个
token ,一个token可能是一个单词、一个词根、标点、标点+单词等等,这种token转换是无损的,有很多算法,例如常用的字节对编码。下图是一个对句子进行向量化的例子。
英文中词汇表大小通常为10K个
token ,上下文长度各模型会有不同,但通常为 2k/4k,有时甚至 100k。根据第一节中的知识,即可算出模型的最大参数值,GPT-3 的最大参数是 175b,而 LLaMA 的最大参数只有 65b。根据向量化后的内容开始训练,过程中,预测分布就会发生变化。开始时,权重是完全随机的,随着 训练时间越来越长,会得到越来越一致和连贯的采样输出。
训练一段时间之后,即可学会单词以及在哪里放空格和逗号等等。随着时间的推移,我们可以得到越来越一致的预测。
完成基础训练后的语言模型功能其实非常单一,它们只想要补全文档,即预测并输出下一个
token,换句话说, 如果你想让它们完成其他任务,就要通过某些方式骗一下它们,让它们以为自己在补全文档。可以采用
few-shot 提示的办法来欺骗它,即将内容整理成问题和答案的形式。我们以提示的形式提出一个问题,它接下来做的事情仍然是它认为的补全文档, 但实际上已经回答了我们的问题。
但是,基础模型不是助手,它们不想回答问题,只想补全文档。
这样训练后的模型是否是否会输出我们期望的内容?不太确定,所以我们需要进行主动干预,主要存在两种办法,SFT(监督微调)或RLHF(强化学习)。
- SFT的主要工作内容为:人工标注员对问题给出一个理想回答,要求这些回答是有帮助的。收集数万条人工数据,进行多轮强化训练。
- RLHF的主要工作内容为:大模型对问题给出多个回答,人工标注员对结果进行排名,对排名后的数据进行强化学习,排名较高的数据在未来将获得更高的出现概率。
一般来说,人类觉得质量从好到坏是:RLHF 模型、SFT 模型、基座模型。RLHF 模型效果好的原因可能是判断比生成简单。而且,RLHF 方法更容易实现,也更实用。
这样,一个能比较好地输出人类想要答案的语言大模型,就可以开始用了。
这种通用的大模型能解决常见问题,但对于法律、数学等专业内容,因为训练用的资料不多,所以效果通常不好。针对特定行业,常见的做法是用开源的语言模型,加上自己掌握的资料进行训练。
开源知识库大模型项目可以自动处理文本数据,进行向量化和 QA 分割,节省手动训练时间,提高效率,适合企业搭建特定场景的大模型。
用最小的资源跑通知识库大模型
下面我来演示一下怎么用参数比较小的Qwen-1.8B-Chat大模型,还有开源的知识库项目FastGPT,以及可以对接大模型API的开源项目One API,在本地搭建一个东西。
通义千问-1.8B(Qwen-1.8B)是阿里云开发的,属于通义千问大模型系列,参数规模是18亿。Qwen-1.8B是一个基于Transformer的大语言模型,它是在很多很多的预训练数据上训练出来的。这些预训练数据有很多种类型,范围也很广,包括网络上的文本、专业的书、代码等等。在Qwen-1.8B的基础上,通过一些方法,做出了一个基于大语言模型的AI助手,就是Qwen-1.8B-Chat。它有int8和int4两种量化版本,推理的时候最少只需要不到2GB的显存,生成2048个tokens只需要3GB的显存。微调的话,最少需要6GB。
FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,它可以直接用,包括数据处理、模型调用这些功能。而且,它还可以通过 Flow 可视化来编排工作流程,这样就可以实现比较复杂的问答场景。
One API 可以让你用标准的 OpenAI API 格式来访问所有的大模型,用起来很方便。
通义千问-1.8B搭建及使用
要求
- python 3.8及以上版本
- pytorch 1.12及以上版本,推荐2.0及以上版本
- 建议使用CUDA 11.4及以上(GPU用户、flash-attention用户等需考虑此选项)
开始搭建
第一步:新建文件夹、创建并进入一个虚拟环境:
第二步:下载依赖项:
第三步:创建启动文件并执行,新建Python文件Qwen-1.8B-Chat.py,内容为:
代码使用了gradio库创建基础页面,要注意的是,如果你是PC电脑,请将
device_map="mps"改为:device_map="gpu"或device_map="cpu"。启动:

第一次运行会下载模型文件,并使用一些Python库,如果报错直接pip3下载即可。
成功运行会创建本地链接,访问即可使用。

以上为基础模型的使用,如果想要与其他知识库大模型项目对接,需要使用openai_api定义好的接口。创建文件openai_api.py,内容为:
启动:

第一次运行会下载模型文件,并使用一些Python库,如果报错直接pip3下载即可。文件包含了大量的Python库使用,缺少的话直接pip3下载。
成功运行会创建本地链接,发起标准请求即可访问,请求内容为:

这样我们的通义千问-1.8B搭建及使用就完成了。
One API 搭建及使用
要求
- x64系统(Mac的M芯片用户可以使用OrbStack软件模拟Ubuntu x64系统)
- Docker环境
开始搭建
直接使用Docker进行搭建,官方建议并发量较大使用
MySQL 模式部署,我们测试的话直接使用SQLite 模式部署即可。因为后续FastGPT默认为3000端口,这里我们使用3001端口部署。启动完成后使用该端口即可访问。

点击渠道-添加新的渠道,按照图里的方式进行填写。

图中的Base URL为本机地址的8000端口,完成后点提交,渠道页面点击测试,在模型界面会收到请求,One API 页面会产生一条报错,适配问题忽略即可。

点击令牌-添加新的令牌,按照图中方式填写,添加完成后点击复制,将生成的令牌密钥保存备用。

另外为了解决知识库向量化的问题,我们搭建m3e对接在One API上,方法如下。
Docker下载并启动m3e:
启动完成后在One API渠道-添加新的渠道界面,按照图里的方式进行填写。

点击测试,使用命令:
docker logs -f 容器ID查看Docker容器中m3e日志,发现收到请求。
至此,One API的搭建就完成了。
FastGPT搭建及使用
要求
- Docker环境
- docker-compose环境
开始搭建
使用docker-compose进行搭建,依次执行命令:
修改docker-compose.yml文件内容,
OPENAI_BASE_URL为One API地址后加v1,CHAT_API_KEY为令牌密钥,如果你是Mac的M芯片用户,无法用 mongo5,需要换成 mongo4.x,完整的配置文件如下:修改config.json文件,添加qwen模型和m3e,完整的配置文件如下:
启动:
使用3000端口即可访问FastGPT页面,点击应用-新建应用,创建一个简单对话应用,AI模型选择qwen,与其对话。

表明qwen模型成功对接。接下来点击知识库-新建-知识库,索引模型选择m3e,确认创建。

手动录入一条你想添加的内容,例如:

回到应用,点击新建应用,选择知识库模版,创建。完成进入,AI模型选择qwen,关联知识库选择刚刚创建的知识库,提问。

恭喜你,搭建完成。
大模型已经彻底改变了我们的生活,搜索平台被语言大模型替代,内容资讯大量由AI生成。
虽然效果最佳的ChatGPT为闭源开发,但现在仍是最好的开源时代。
参考链接:https://colab.research.google.com/drive/1SiF0KZJp75rUeetKOWqpsA8clmHP6jMg https://build.microsoft.com/en-US/sessions/db3f4859-cd30-4445-a0cd-553c3304f8e2 https://huggingface.co/Qwen/Qwen-1_8B-Chat https://github.com/labring/FastGPT https://github.com/songquanpeng/one-api


