大模型学习笔记

prompt

提示词的构成:

  • 指示:描述让它做什么
  • 上下文:给出与任务相关的背景信息
  • 输入: 任务的输入信息
  • 输出:输出的格式

生成与检索

生成:

  • 优点:内容的多样性、创造性
  • 缺点:存在不可控制
    检索:
  • 优点:可控
  • 缺点:内容的边界有限制
    通过RAG结合生成与检索

智能客服

传统方法+检索:

  • 设置很多Q(问题),A(答案)对库
  • 当一个问题到来,比较Query和库中的那个Q最接近,则回答对应的答案

传统方法+生成:

  • 通过Q,A对训练一个模型
  • 使用时给一个Q,输出一个答案

大模型方法(检索+生成):

  • 创建一个知识库(中间有各种各样的文档)
  • 用户给了一个Q,在知识库中检索相关的内容(candidate)
  • 把检索到的内容和Q以及message(过去的信息)放到prompt中
  • 将prompt放入LLm生成答案

知识库的搭建

  • 收集很多相关文档
  • 将每个文档都分割成若干个trunk得到完整的知识库
  • 将trunk转化为向量,得到向量库
  • 将Q进行向量化
  • 找到和Q相关的trunk,将相关的trunk和Q放入prompt中

把文本切分成Trunks

  1. 根据句子切分
  2. 按照字符数切分
  3. 按固定字符数,结合overlapping window(紧挨着的两个trunk末尾和开头有一定的重叠)
  4. 递归方法(按字符切分,考虑语义)
  5. 根据语义分割

倒排索引

  1. 将Query进行切分
  2. 查找切分的Query每个部分出现的文档列表
  3. 找到特定几个比较重要的文档列表的并集
  4. 进行排序

快速搜索向量

KNN搜索

将Q的向量和向量库中的向量一一对比,计算距离或相似度

精确度高,速度慢,适合小数据集

近似KNN算法

  1. 将数据分成若干模块,每个模块有个中心点
  2. 查找和query最近的中心点
  3. 计算中心点所在区域中所有点和Query的距离

Product Quantization(PQ)

  1. 将向量切分成几段短向量(例如长为256的短向量)
  2. 将长为256的短向量划分为若干区域,每个区域对应一个ID
  3. 将Q切分后的短向量和每个区域中心点进行计算距离
  4. 将Q切分后的短向量转换为区域中心距离最近的区域的ID
  5. 将生成的ID没向量库中的向量的ID进行对比计算距离

Optimized Approach(改进PQ)

  1. 将Q分解成n段,有k个中心点
  2. 将Q的每段和每个中心点对应的小段计算距离,得到一个k×n的矩阵
  3. 将向量库的向量和Q的距离近似为距离这个向量最近的中心点和Q的距离
  4. 计算出中心点的距离即为这个向量和Q的距离

langchain

langchain是面向大模型开发的框架

Langchain的核心组件

  • 模型I/O封装:包括大预言模型,chat Model,Prompt Template,output parser等

  • Retrieval:包括文档的loader,embedding模型,Text Splitter,向量存储,检索等

  • chain: 实现一个功能或者一系列功能

  • Agent: 给定用户的输入,以及可使用的tools,自动规划执行步骤(比如每个步骤调用哪些tool),并最终完成用户指令

  • 记忆: 模型记忆里的管理

  • Prompt Template:管理和格式化提示词

  • chains: 串联多步流程

  • Memory:保存上下文,实现多轮对话

  • Retrieval+VectorStore :现在知识库检索,在生成回答

两种模型:

  • non-chat model:非对话模型,给一句话,补全这句话
  • chat model:对话模型

非Agent: 对于一个任务,明确指定每一步应该做什么

Agent: Agent的核心任务是将一个复杂的问题拆解成几个简单的任务

提示词工程

python 复制代码
from langchain_openai.chat_models.base import BaseChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
# 初始化LLM

llm = ChatOpenAI(model_name='gpt-3.5-turbo')

template ='写一首描述{sence}的诗,格式要求为{type}'

# 方法一,自动发现参数
prompt = PromptTemplate.from_template(template)   #创建模板

# 方法二,指定参数
prompt = PromptTemplate(
    template = template,
    input_variables = ['type','sence']
)


chain = LLMChain(llm=llm, prompt=prompt)

# 调用大模型
# 方法一
chain.predict(snece='春天',type='五言绝句')    # 调用大模型

# 方法二
chain.run({'sence':'秋天','type':'五言绝句'})
chain({'sence':'秋天','type':'五言绝句'})         # 底层也是调用chain.run

# 方法三
chain.apply([{'sence':'秋天','type':'五言绝句'}])

chain.generate([{'sence':'秋天','type':'五言绝句'}])

few shot

python 复制代码
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(model='gpt-3.5-turbo-1106', temperature=0)

from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.prompts import FewShotPromptTemplate


examples = [
  {'sence': '秋天', 'type': '五言绝句', 'text': '移舟泊烟渚,日暮客愁新。\n野旷天低树,江清月近人。'},
  {'sence': '冬天', 'type': '七言律诗', 'text': '昔人已乘黄鹤去,此地空余黄鹤楼。\n黄鹤一去不复返,白云千载空悠悠。\n晴川历历汉阳树,芳草萋萋鹦鹉洲。\n日暮乡关何处是?烟波江上使人愁。'},
]

example_template = '这是一首描写{sence}的诗,格式为{type}:\n{text}'
example_prompt = PromptTemplate.from_template(example_template)
# 例子放在前缀和后缀之间
prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    example_separator='\n\n',
    prefix='请分析以下诗歌的格式,并按格式要求创作诗歌。',		# 前缀
    suffix='写一首描写{sence}的诗,格式要求为{type}:\n',		# 后缀
    input_variables=['sence', 'type',]
)

# print(prompt.format(sence='秋天', type='七言律诗'))

chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run({'sence':'夏天', 'type':'七言律诗'})
print(result)

多个chain进行串联(组合链)

python 复制代码
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(model='gpt-3.5-turbo-1106', temperature=0)

from langchain.chains import LLMChain
from langchain.chains import SequentialChain
from langchain.prompts import PromptTemplate

prompt1 = PromptTemplate.from_template(
    '有一家公司的创始人叫{name},主要从事人工智能技术培训和科研辅导,请帮这家公司起10个中文名字,要求包含创始人的名字。'
)

chain1 = LLMChain(llm=llm, prompt=prompt1, output_key='company_names', verbose=True)
# print(chain1.predict(name='陈华'))
# company_names = chain1.predict(name='陈华')

prompt2 = PromptTemplate.from_template(
    '请从以下公司名字中,选出你认为最好的一个:\n {company_names}'
)

chain2 = LLMChain(llm=llm, prompt=prompt2, verbose=True)
# print(chain2.predict(company_names=company_names))

chain = SequentialChain(chains=[chain1, chain2], input_variables=['name'], verbose=True)
result = chain.run({'name':'陈华'})
print(result)

内置组合链

python 复制代码
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI

load_dotenv()
llm = ChatOpenAI(model='gpt-3.5-turbo-1106', temperature=0)

# # 简单对话场景
# from langchain.chains import ConversationChain

# conversation = ConversationChain(llm=llm, verbose=True)
# # print(conversation.prompt.template)

# while True:
#     human_input = input('User: ')  # hello | 你叫什么名字?
#     result = conversation.predict(input=human_input)
#     print('Assistant: ', result)


# 修改提示词
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate

template = '''
下面是一段人类和人工智能之间的友好对话。人工智能是健谈的,并根据其上下文提供许多具体细节。如果人工智能不知道一个问题的答案,它就会如实说它不知道。 
请注意,无论人类用什么语言,你都用中文进行回复。

当前对话:
{history}
User:{input}
Assistant:
'''
prompt = PromptTemplate.from_template(template)

conversation = ConversationChain(llm=llm, prompt=prompt, verbose=True)
# print(conversation.prompt.template)

while True:
    human_input = input('User: ')  # hello | 你叫什么名字? | 感冒吃什么药好得快?
    result = conversation.predict(input=human_input)
    print('Assistant: ', result)

langchain Memory

随着提问的次数增加,Memory中存储的内容会越来越多,context中的token越来越多

解决方法:

只考虑n轮的Memory

对会话内容进行总结

python 复制代码
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import (ConversationBufferMemory,
                              ConversationBufferWindowMemory,
                              ConversationSummaryMemory,
                              ConversationSummaryBufferMemory)

load_dotenv()
llm = ChatOpenAI(model='gpt-3.5-turbo-1106')


# memory = ConversationBufferWindowMemory(k=3)
# conversation = ConversationChain(llm=llm, memory=memory, verbose=True)

# memory = ConversationBufferMemory()  # 保留完整会话(默认)
# memory = ConversationBufferWindowMemory(k=2)  # 保留前k轮会话
# memory = ConversationSummaryMemory(llm=llm)  # 总结前面的对话内容
memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)  # 超过最大token数量的会话,会被总结

conversation = ConversationChain(llm=llm, memory=memory, verbose=True)

result = conversation.predict(input='hello')
result = conversation.predict(input='你叫什么名字?')

result = conversation.predict(input='感冒是一种什么病?')
result = conversation.predict(input='一般会有哪些症状?')
result = conversation.predict(input='吃什么药好得快?')
print(result)

RequestsChain

针对大模型不知道的内容,使用搜索引擎搜索相关内容,然后让大模型进行总结

python 复制代码
from langchain.chat_models import ChatOpenAI
from dotenv import load_dotenv

load_dotenv()
llm = ChatOpenAI(model='gpt-3.5-turbo-1106')

from langchain.chains import LLMRequestsChain
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate


prompt = PromptTemplate.from_template('''
请根据如下搜索结果,回答用户问题。
搜索结果:
-----------
{requests_result}
-----------
问题:{question}
回答:
''')

llm_chain = LLMChain(llm=llm, prompt=prompt, verbose=True)

chain = LLMRequestsChain(
    llm_chain=llm_chain,
    verbose=True
)

# question = '刀郎最近发布了什么新专辑?'
question = '陈华编程是什么?'

inputs = {
    'question': question,
    'url': 'https://www.google.com/search?q=' + question.replace(' ', '+')  # google地址+问题
}

result = chain.run(inputs)
print(result)

问答QAchain

python 复制代码
from langchain.chat_models import ChatOpenAI
from dotenv import load_dotenv

load_dotenv()

llm = ChatOpenAI(model='gpt-3.5-turbo-1106', temperature=0)

# 构建文档库
from langchain.schema import Document

corpus = [
    '武汉市,简称"汉",别称江城,湖北省辖地级市、省会,副省级市、国家中心城市、超大城市,国务院批复确定的中国中部地区的中心城市。',  
    '武汉市下辖13个区,总面积8569.15平方千米。截至2022年末,常住人口1373.90万人,地区生产总值18866.43亿元。',
    '武汉市地处江汉平原东部、长江中游,长江及其最大支流汉水在此交汇,形成武汉三镇(武昌、汉口、汉阳)隔江鼎立的格局。',
    '湖北省,简称"鄂",别名楚、荆楚,中华人民共和国省级行政区,省会武汉。',
    '湖北省辖12个地级市、1个自治州,39个市辖区、26个县级市、37个县(其中2个自治县)、1个林区。',
    '截至2022年末,湖北省常住人口5844万人,地区生产总值为53734.92亿元,人均地区生产总值为92059元。',
]

documents = [Document(page_content=cp) for cp in corpus]
# print(documents)

from langchain.chains.question_answering import load_qa_chain

chain = load_qa_chain(llm=llm, chain_type='map_rerank', verbose=True)

# question = '武汉三镇是哪三个?'
question = '湖北省常住人口是多少?'

result = chain.run(input_documents=documents, question=question)
print(result)

FAISS 文档召回

python 复制代码
from langchain.vectorstores.faiss import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.schema import Document
from dotenv import load_dotenv
from langchain.chat_models import ChatOpenAI


from langchain.chains.question_answering import load_qa_chain


load_dotenv()
llm = ChatOpenAI(model='gpt-3.5-turbo-1106', temperature=0)

corpus = [
    '武汉市,简称"汉",别称江城,湖北省辖地级市、省会,副省级市、国家中心城市、超大城市,国务院批复确定的中国中部地区的中心城市。',  
    '武汉市下辖13个区,总面积8569.15平方千米。截至2022年末,常住人口1373.90万人,地区生产总值18866.43亿元。',
    '武汉市地处江汉平原东部、长江中游,长江及其最大支流汉水在此交汇,形成武汉三镇(武昌、汉口、汉阳)隔江鼎立的格局。',
    '湖北省,简称"鄂",别名楚、荆楚,中华人民共和国省级行政区,省会武汉。',
    '湖北省辖12个地级市、1个自治州,39个市辖区、26个县级市、37个县(其中2个自治县)、1个林区。',
    '截至2022年末,湖北省常住人口5844万人,地区生产总值为53734.92亿元,人均地区生产总值为92059元。',
]

documents = [Document(page_content=cp) for cp in corpus]

embedding = OpenAIEmbeddings(model='text-embedding-ada-002')
documents_db = FAISS.from_documents(documents, embedding)

chain = load_qa_chain(llm=llm, chain_type='stuff', verbose=True)

question = '武汉三镇是哪三个?'
# question = '湖北省常住人口是多少?'

# 检索出最相关的内容
retrieval_documents = documents_db.max_marginal_relevance_search(question, k=3)         # 最大边际搜索,优化了与查询的相似性和文档之间的多样性
retrieval_documents = documents_db.similarity_search(question, k=3)                     # 相似性搜索,返回最相关的k条信息
retrieval_documents = documents_db.similarity_search_with_score(question, k=3)          # 相似性搜索,并且返回相似度分数,分数越小越相关
retrieval_documents = documents_db.similarity_search_with_relevance_scores(question)    # 相似性搜索,分数越大越相关

print(retrieval_documents)
exit()

result = chain.run(input_documents=retrieval_documents, question=question)
print(result)

读取文档并分割

python 复制代码
from langchain.document_loaders import CSVLoader, TextLoader, PyMuPDFLoader
import os

file_dir = os.path.dirname(__file__)

# loader = CSVLoader(os.path.join(file_dir, './data/about.csv'))
# print(len(loader.load()))

# loader = PyMuPDFLoader(os.path.join(file_dir, './data/about.pdf'))
# loader = TextLoader(os.path.join(file_dir, './data/about.txt'))

# print(loader.load())

# 加载并分割文档
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    # separator = ['\n\n', '\n', ' ', ''],
    chunk_size = 50,  # default:4000
    chunk_overlap = 10,  # default:200
)

loader = TextLoader(os.path.join(file_dir,'./data/about.txt'))
documents = loader.load_and_split(text_splitter)

print(documents)

LLama

即便模型规模小,资源有限,如果选择适当的训练方法,用足够多高质量的数据训练足够长的时间,也能得到一个较好的模型

相关推荐
XIAO·宝32 分钟前
PyCharm 在手,NumPy 函数实操笔记:从字符串到统计分析,一篇搞懂
笔记·pycharm·numpy
2301_8016730138 分钟前
ipv6学习
linux·服务器·学习
F_D_Z1 小时前
【感知机】感知机(perceptron)学习算法的对偶形式
人工智能·学习·算法·支持向量机
₯㎕星空&繁华1 小时前
接口自动化-pytest
运维·经验分享·笔记·自动化·pytest·接口
AI视觉网奇3 小时前
nohup 学习笔记
笔记·学习
MUTA️4 小时前
《CogAgent: A Visual Language Model for GUI Agents》论文精读笔记
人工智能·笔记·语言模型·多模态
Asu52025 小时前
思途spring学习0807
java·开发语言·spring boot·学习
胤祥矢量商铺6 小时前
菜鸟笔记007 [...c(e), ...d(i)]数组的新用法
c语言·开发语言·javascript·笔记·illustrator插件
泽虞6 小时前
C语言深度语法掌握笔记:底层机制,高级概念
java·c语言·笔记