一文读懂LLM大模型工作原理

708 阅读9分钟

一、 大模型是怎样工作的?

通俗原理

其实,它只是根据上文,猜下一个词(的概率)…… 训练:

  1. 大模型阅读了人类说过的所有的话。这就是 「机器学习

  2. 训练过程会把不同 token 同时出现的概率存入 「神经网络」文件。保存的数据就是「参数」,也叫「权重

推理:

  1. 我们给推理程序若干 token,程序会加载大模型权重,算出概率最高的下一个 token 是什么

  2. 用生成的 token,再加上上文,就能继续生成下一个 token。以此类推,生成更多文字

Token 是什么?

  1. 可能是一个英文单词,也可能是半个,三分之一个

  2. 可能是一个中文词,或者一个汉字,也可能是半个汉字,甚至三分之一个汉字

  3. 大模型在开训前,需要先训练一个 tokenizer 模型。它能把所有的文本,切成 token

架构:

  • 这套生成机制的内核叫「Transformer 架构」

  • Transformer 是目前人工智能领域最广泛流行的架构,被用在各个领域

  • Transformer 仍是主流,但并不是最先进的

目前只有 transformer 被证明了符合 scaling-law。

大模型应用技术架构

纯 Prompt

Agent + Function Calling

RAG(Retrieval-Augmented Generation)
  • Embeddings:把文字转换为更易于相似度计算的编码。这种编码叫向量

  • 向量数据库:把向量存起来,方便查找

  • 向量搜索:根据输入向量,找到最相似的向量

Fine-tuning(精调/微调)

面对一个需求,如何开始,如何选择技术方案?

二、Prompt工程

大模型只接受一种输入,那就是 prompt

主要要求:指令具体、信息丰富、减少歧义

Prompt 的典型构成

  • 角色:给 AI 定义一个最匹配任务的角色,比如:「你是一位软件工程师」「你是一位小学老师」

大模型对 prompt 开头和结尾的内容更敏感,先定义角色,其实就是在开头把问题域收窄,减少歧义。

  • 指示:对任务进行描述

  • 上下文:给出与任务相关的其它背景信息(尤其在多轮交互中)

  • 例子:必要时给出举例,学术中称为 Few-Shot Learning 或 In-Context Learning;这对对输出正确性有很大帮助

  • 输入:任务的输入信息;在提示词中明确的标识出输入

  • 输出:输出的风格、格式描述,引导只输出想要的信息,以及方便后继模块自动解析模型的输出结果,比如(JSON、XML)

思维链(Chain of Thoughts, CoT)

  • 论文地址:arxiv.org/abs/2205.11…
  • 发现 prompt 以「Let’s think step by step」开头,AI 就会把问题分解成多个步骤,然后逐步解决,使得输出的结果更加准确。它是偶然被「发现」的(OpenAI 的人在训练时没想过会这样)

自洽性(Self-Consistency)

一种对抗「幻觉」的手段。就像我们做数学题,要多次验算一样。

  • 同样 prompt 跑多次(把 temperature 设大,比如 0.9;或每次用不同的 temperature)

  • 通过投票选出最终结果

思维树(Tree-of-thought, ToT)

  • 在思维链的每一步,采样多个分支

  • 拓扑展开成一棵思维树

  • 判断每个分支的任务完成度,以便进行启发式搜索

  • 设计搜索算法

  • 判断叶子节点的任务完成的正确性

  1. 最简单的是:直接大白话问一次 (IO)
  2. 进阶一点是:思维链,让一步步思考(CoT)
  3. 再进一步是:思维链问多次,出结果后选举——少数服从多数(CoT-SC)
  4. 思维树=思维链问多次+链里每一步的逐步选举(ToT)

prompt示例整理

和人一样,更多例子、更好的例子、多次验算,都能提升正确率。

三、RAG

LLM 固有的局限性

  1. LLM 的知识不是实时的

  2. LLM 可能不知道你私有的领域/业务知识

RAG 系统的基本搭建流程

搭建过程:

  1. 文档加载,并按一定条件切割成片段

  2. 将切割的文本片段灌入检索引擎

  3. 封装检索接口

  4. 构建调用流程:Query -> 检索 -> Prompt -> LLM -> 回复

ES检索(关键词拆分后入库)

将文本灌入检索引擎

import os, time
from elasticsearch import Elasticsearch, helpers

# 1. 创建Elasticsearch连接
es = Elasticsearch(
    hosts=[ELASTICSEARCH_BASE_URL],  # 服务地址与端口
    http_auth=(ELASTICSEARCH_NAME, ELASTICSEARCH_PASSWORD),  # 用户名,密码
)

# 2. 定义索引名称
index_name = "teacher_demo_index"

# 3. 创建索引
es.indices.create(index=index_name)

# 4. 灌库指令
actions = [
    {
        "_index": index_name,
        "_source": {
            "keywords": to_keywords(para),
            "text": para
        }
    }
    for para in paragraphs
]

# 6. 文本灌库
helpers.bulk(es, actions)

# 灌库是异步的
time.sleep(2)

实现关键字检索

def search(query_string, top_n=3):
    # ES 的查询语言
    search_query = {
        "match": {
            "keywords": to_keywords(query_string)
        }
    }
    res = es.search(index=index_name, query=search_query, size=top_n)
    return [hit["_source"]["text"] for hit in res["hits"]["hits"]]
向量检索
文本向量(Text Embeddings)
  1. 将文本转成一组 𝑁 维浮点数,即文本向量又叫 Embeddings。
  2. 向量之间可以计算距离,距离远近对应语义相似度大小。

向量数据库

专门为向量检索设计的中间件。

几个关键概念
  1. 向量数据库的意义:快速的检索。
  2. 向量数据库本身不生成向量:向量是由 Embedding 模型产生的。
  3. 向量数据库与传统的关系型数据库是互补的:不是替代关系,在实际应用中根据实际需求经常同时使用。
思考优化的点

一、 文本分割的粒度

  • 粒度太大可能导致检索不精准,粒度太小可能导致信息不全面。
  • 问题的答案可能跨越两个片段

改进:

  1. 按一定粒度,部分重叠式的切割文本,使上下文更完整。
  2. 单文本块多向量:
  • 首先将文本分割为长度300-500 token的文本块,这些文本块被用于向量检索。但是在构建向量时,我们不是利用这个文本块得到一个向量,而是将文本块拆分为一个个句子,得到每个句子的向量表示,如果其中一个句子的向量表示和用户的query向量相似度足够高,整个文本块就会被检索回来
  1. 补充标题信息: 针对 Markdown 这种有明显章节结构的文档,按章节进行文本分割,并在文本开头补充对应章节的标题信息。

二、检索后排序 有时,最合适的答案不一定排在检索的最前面

方案

  1. 检索时过招回一部分文本。
  2. 通过一个排序模型对 query 和 document 重新打分排序。

  1. 混合检索(Hybrid Search) 传统的关键字检索(稀疏表示)与向量检索(稠密表示)各有优劣。

举个具体例子,比如文档中包含很长的专有名词,关键字检索往往更精准而向量检索容易引入概念混淆。

# 背景说明:在医学中“小细胞肺癌”和“非小细胞肺癌”是两种不同的癌症

query = "非小细胞肺癌的患者"

documents = [
    "玛丽患有肺癌,癌细胞已转移",
    "刘某肺癌I期",
    "张某经诊断为非小细胞肺癌III期",
    "小细胞肺癌是肺癌的一种"
]

query_vec = get_embeddings([query])[0]
doc_vecs = get_embeddings(documents)

print("Cosine distance:")
for vec in doc_vecs:
    print(cos_sim(query_vec, vec))
    return [hit["_source"]["text"] for hit in res["hits"]["hits"]]

结果:

Cosine distance:
0.8915268056308027
0.8895478505819983
0.9039165614288258
0.9131441645902685]

所以,有时候我们需要结合不同的检索算法,来达到比单一检索算法更优的效果。这就是混合检索。

混合检索的核心是,综合文档 𝑑 在不同检索算法下的排序名次(rank),为其生成最终排序。

一个最常用的算法叫 Reciprocal Rank Fusion(RRF)

该方法的优势在于不利用相关分数,而仅靠排名计算

其中 𝐴 表示所有使用的检索算法的集合,𝑟𝑎𝑛𝑘𝑎(𝑑) 表示使用算法 𝑎 检索时,文档 𝑑 的排序,𝑘 是个常数。

很多向量数据库都支持混合检索,比如 Weaviate、Pinecone 等。也可以根据上述原理自己实现。

  1. RAG-Fusion

RAG-Fusion 就是利用了 RRF 的原理来提升检索的准确性。 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. PDF 文档中的表格怎么处理

总结

RAG 的流程

离线步骤
  1. 文档加载:将文档加载到系统中。
  2. 文档切分:按一定条件切割成片段。
  3. 向量化:将切割的文本片段灌入检索引擎。
  4. 灌入向量数据库:将向量存入向量数据库。
在线步骤
  1. 获得用户问题:获取用户输入的问题。
  2. 用户问题向量化:将用户问题转换为向量。
  3. 检索向量数据库:从向量数据库中检索与问题相关的文档。
  4. 将检索结果和用户问题填入 Prompt 模版:将检索结果和用户问题一起输入大模型。 用最终获得的 Prompt 调用 LLM:由 LLM 生成回复。

希望这篇文章能给你带来一些启发和帮助。

如果你觉得有用,别忘了点赞、分享给更多的朋友哦!

欢迎关注公众号「编程复盘与思考随笔」

看更多走心好文请下面公众号关注:

在这里插入图片描述

关注后台私信【搞钱】送0基础搞钱方法手把手教程,一起搞钱!

点亮【关注、赞和在看】,让钱和爱都流向你。

欢迎加入我的2024年VIP群,大家一起成长。若想进一步了解,请选择以下通道详询!(备注来意:【发财】)

在这里插入图片描述