调用模型以及输出解析
预训练+微调的模式
图中的“具体任务”,其实也可以更换为“具体领域”。那么总结来说:
- 预训练:在大规模无标注文本数据上进行模型的训练,目标是让模型学习自然语言的基础表达、上下文信息和语义知识,为后续任务提供一个通用的、丰富的语言表示基础。
- 微调:在预训练模型的基础上,可以根据特定的下游任务对模型进行微调。现在你经常会听到各行各业的人说:我们的优势就是领域知识嘛!我们比不过国内外大模型,我们可以拿开源模型做垂直领域嘛!做垂类模型! —— 啥叫垂类?指的其实就是根据领域数据微调开源模型这件事儿。
优点:
- 预训练模型能够将大量的通用语言知识迁移到各种下游任务上,作为应用人员,不需要自己寻找语料库,从头开始训练大模型,这减少了训练时间和数据需求。
- 其次,微调过程可以快速地根据特定任务进行优化,简化了模型部署的难度。
- 最后,预训练+微调的架构具有很强的可扩展性,可以方便地应用于各种自然语言处理任务,大大提高了NLP技术在实际应用中的可用性和普及程度,带来了巨大的便利。
通过 HuggingFace 调用 Llama
# 导入必要的库
from transformers import AutoTokenizer, AutoModelForCausalLM
# 加载预训练模型的分词器
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-chat-hf")
# 加载预训练的模型
# 使用 device_map 参数将模型自动加载到可用的硬件设备上,例如GPU
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-2-7b-chat-hf",
device_map = 'auto')
# 定义一个提示,希望模型基于此提示生成故事
prompt = "请给我讲个玫瑰的爱情故事?"
# 使用分词器将提示转化为模型可以理解的格式,并将其移动到GPU上
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
# 使用模型生成文本,设置最大生成令牌数为2000
outputs = model.generate(inputs["input_ids"], max_new_tokens=2000)
# 将生成的令牌解码成文本,并跳过任何特殊的令牌,例如[CLS], [SEP]等
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
# 打印生成的响应
print(response)
- 导入AutoTokenizer:这是一个用于自动加载预训练模型的相关分词器的工具。分词器负责将文本转化为模型可以理解的数字格式。
- 导入AutoModelForCausalLM:这是用于加载因果语言模型(用于文本生成)的工具。
- 使用from_pretrained方法来加载预训练的分词器和模型。其中,
device_map = 'auto'
是为了自动地将模型加载到可用的设备上,例如GPU。 - 然后,给定一个提示(prompt):
"请给我讲个玫瑰的爱情故事?"
,并使用分词器将该提示转换为模型可以接受的格式,return_tensors="pt"
表示返回PyTorch张量。语句中的.to("cuda")
是GPU设备格式转换,在GPU上跑程序,不用这个的话会报错,如果你使用CPU,可以试一下删掉它。 - 最后使用模型的
.generate()
方法生成响应。max_new_tokens=2000
限制生成的文本的长度。使用分词器的.decode()
方法将输出的数字转化回文本,并且跳过任何特殊的标记。
LangChain 中的输出解析器
输出解析器是一种专用于处理和构建语言模型响应的类。一个基本的输出解析器类通常需要实现两个核心方法。
- get_format_instructions:这个方法需要返回一个字符串,用于指导如何格式化语言模型的输出,告诉它应该如何组织并构建它的回答。
- parse:这个方法接收一个字符串(也就是语言模型的输出)并将其解析为特定的数据结构或格式。这一步通常用于确保模型的输出符合我们的预期,并且能够以需要的形式进行后续处理。
- parse_with_prompt:这个方法接收一个字符串(也就是语言模型的输出)和一个提示(用于生成这个输出的提示),并将其解析为特定的数据结构。这样,可以根据原始提示来修正或重新解析模型的输出,确保输出的信息更加准确和贴合要求。
各种输出解析器:
- 列表解析器(List Parser):这个解析器用于处理模型生成的输出,当需要模型的输出是一个列表的时候使用。例如,如果你询问模型“列出所有鲜花的库存”,模型的回答应该是一个列表。
- 日期时间解析器(Datetime Parser):这个解析器用于处理日期和时间相关的输出,确保模型的输出是正确的日期或时间格式。
- 枚举解析器(Enum Parser):这个解析器用于处理预定义的一组值,当模型的输出应该是这组预定义值之一时使用。例如,如果你定义了一个问题的答案只能是“是”或“否”,那么枚举解析器可以确保模型的回答是这两个选项之一。
- 结构化输出解析器(Structured Output Parser):这个解析器用于处理复杂的、结构化的输出。如果你的应用需要模型生成具有特定结构的复杂回答(例如一份报告、一篇文章等),那么可以使用结构化输出解析器来实现。
- Pydantic(JSON)解析器:这个解析器用于处理模型的输出,当模型的输出应该是一个符合特定格式的JSON对象时使用。它使用Pydantic库,这是一个数据验证库,可以用于构建复杂的数据模型,并确保模型的输出符合预期的数据模型。
- 自动修复解析器(Auto-Fixing Parser):这个解析器可以自动修复某些常见的模型输出错误。例如,如果模型的输出应该是一段文本,但是模型返回了一段包含语法或拼写错误的文本,自动修复解析器可以自动纠正这些错误。
- 重试解析器(RetryWithErrorOutputParser):这个解析器用于在模型的初次输出不符合预期时,尝试修复或重新生成新的输出。例如,如果模型的输出应该是一个日期,但是模型返回了一个字符串,那么重试解析器可以重新提示模型生成正确的日期格式。
Pydantic(JSON)解析器
Pydantic有这样几个特点。
- 数据验证:当你向Pydantic类赋值时,它会自动进行数据验证。例如,如果你创建了一个字段需要是整数,但试图向它赋予一个字符串,Pydantic会引发异常。
- 数据转换:Pydantic不仅进行数据验证,还可以进行数据转换。例如,如果你有一个需要整数的字段,但你提供了一个可以转换为整数的字符串,如
"42"
,Pydantic会自动将这个字符串转换为整数42。 - 易于使用:创建一个Pydantic类就像定义一个普通的Python类一样简单。只需要使用Python的类型注解功能,即可在类定义中指定每个字段的类型。
- JSON支持:Pydantic类可以很容易地从JSON数据创建,并可以将类的数据转换为JSON格式。
创建步骤:
- 第一步:创建模型实例
- 第二步:定义输出数据的格式
- 第三步:创建输出解析器
- 第四步:创建提示模板
- 第五步:生成提示,传入模型并解析输出
总结
- PyTorch是一个流行的深度学习框架,常用于模型的训练和微调。
- HuggingFace是一个开源社区,提供了大量预训练模型和微调工具,尤其是NLP任务。
- LangChain则擅长于利用大语言模型的推理功能,开发新的工具或应用,完成特定的任务。
- 结构化解析器和Pydantic解析器都旨在从大型语言模型中获取格式化的输出。结构化解析器更适合简单的文本响应,而Pydantic解析器则提供了对复杂数据结构和类型的支持。
- 自动修复解析器主要适用于纠正小的格式错误,仅在原始输出出现问题时进行修复。重试解析器则可以处理更复杂的问题,包括格式错误和内容缺失。它通过重新与模型交互,使得输出更加完整和符合预期。