这一块主要讲解的是有关llm的内容
预训练与微调
预训练过程需要大量的数据、gpu硬件以及强大的工程能力,因此预训练过程往往个人难以展开,大部分聚焦于微调。微调只需要少量的有标签数据,通过调整头部参数就能轻松的将大模型在上游学到的词汇、语法、句子结果等语义信息迁移到各种下游任务中,非常方便。
- 预训练:在大规模无标注文本数据上进行模型的训练,目标是让模型学习自然语言的基础表达、上下文信息和语义知识,为后续任务提供一个通用的、丰富的语言表示基础。
- 微调:在预训练模型的基础上,可以根据特定的下游任务对模型进行微调。现在你经常会听到各行各业的人说:我们的优势就是领域知识嘛!我们比不过国内外大模型,我们可以拿开源模型做垂直领域嘛!做垂类模型! —— 啥叫垂类?指的其实就是根据领域数据微调开源模型这件事儿。
用Huggingface跑开源模型
- 到huggingface中去申请个人API token,这样就可以使用库函数直接去访问开源的模型、数据集等等。其实这个API Token就是一个你的身份令牌,任何需要验证身份的地方肯定需要你提供你的API Token。这里我们使用llama3模型,使用这个模型要求我们先进行一个申请,只有申请通过才能使用他的模型。我感觉这个申请通过应该是和你的API Token绑定在一起的,以此来验证是否有资格下载模型。
# 导入必要的库
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)
将LangChain与HuggingFace中的模型接在一起
通过 HuggingFace Hub
HuggingFace Hub 是一个开源模型中心化存储库,主要用于分享、协作和存储预训练模型、数据集以及相关组件。
# 导入HuggingFace API Token
import os
os.environ['HUGGINGFACEHUB_API_TOKEN'] = '你的HuggingFace API Token'
# 导入必要的库
from langchain import PromptTemplate, HuggingFaceHub, LLMChain
# 初始化HF LLM
llm = HuggingFaceHub(
repo_id="google/flan-t5-small",
#repo_id="meta-llama/Llama-2-7b-chat-hf",
)
# 创建简单的question-answering提示模板
template = """Question: {question}
Answer: """
# 创建Prompt
prompt = PromptTemplate(template=template, input_variables=["question"])
# 调用LLM Chain --- 我们以后会详细讲LLM Chain
llm_chain = LLMChain(
prompt=prompt,
llm=llm
)
# 准备问题
question = "Rose is which type of flower?"
# 调用模型并返回结果
print(llm_chain.run(question))
通过 HuggingFace Pipeline
# 指定预训练模型的名称
model = "meta-llama/Llama-2-7b-chat-hf"
# 从预训练模型中加载词汇器
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(model)
# 创建一个文本生成的管道
import transformers
import torch
pipeline = transformers.pipeline(
"text-generation",
model=model,
torch_dtype=torch.float16,
device_map="auto",
max_length = 1000
)
# 创建HuggingFacePipeline实例
from langchain import HuggingFacePipeline
llm = HuggingFacePipeline(pipeline = pipeline,
model_kwargs = {'temperature':0})
# 定义输入模板,该模板用于生成花束的描述
template = """
为以下的花束生成一个详细且吸引人的描述:
花束的详细信息:
```{flower_details}```
"""
# 使用模板创建提示
from langchain import PromptTemplate, LLMChain
prompt = PromptTemplate(template=template,
input_variables=["flower_details"])
# 创建LLMChain实例
from langchain import PromptTemplate
llm_chain = LLMChain(prompt=prompt, llm=llm)
# 需要生成描述的花束的详细信息
flower_details = "12支红玫瑰,搭配白色满天星和绿叶,包装在浪漫的红色纸中。"
# 打印生成的花束描述
print(llm_chain.run(flower_details))
这块也没啥好说的,就是调用pipline的方式进行调用模型实现某种特定的任务如"text-generation",当然也可以是别的任务如"text-classification","question-answering","summarization"等等。
用LangChain调用自定义语言模型
假设我们微调后的模型为:llama-2-7b-chat.ggmlv3.q4_K_S.bin这个二进制文件。为了使用llama-2-7b-chat.ggmlv3.q4_K_S.bin这个模型,你需要安装 pip install llama-cpp-python 这个包。
# 导入需要的库
from llama_cpp import Llama
from typing import Optional, List, Mapping, Any
from langchain.llms.base import LLM
# 模型的名称和路径常量
MODEL_NAME = 'llama-2-7b-chat.ggmlv3.q4_K_S.bin'
MODEL_PATH = '/home/huangj/03_Llama/'
# 自定义的LLM类,继承自基础LLM类
class CustomLLM(LLM):
model_name = MODEL_NAME
# 该方法使用Llama库调用模型生成回复
def _call(self, prompt: str, stop: Optional[List[str]] = None) -> str:
prompt_length = len(prompt) + 5
# 初始化Llama模型,指定模型路径和线程数
llm = Llama(model_path=MODEL_PATH+MODEL_NAME, n_threads=4)
# 使用Llama模型生成回复
response = llm(f"Q: {prompt} A: ", max_tokens=256)
# 从返回的回复中提取文本部分
output = response['choices'][0]['text'].replace('A: ', '').strip()
# 返回生成的回复,同时剔除了问题部分和额外字符
return output[prompt_length:]
# 返回模型的标识参数,这里只是返回模型的名称
@property
def _identifying_params(self) -> Mapping[str, Any]:
return {"name_of_model": self.model_name}
# 返回模型的类型,这里是"custom"
@property
def _llm_type(self) -> str:
return "custom"
# 初始化自定义LLM类
llm = CustomLLM()
# 使用自定义LLM生成一个回复
result = llm("昨天有一个客户抱怨他买了花给女朋友之后,两天花就枯了,你说作为客服我应该怎么解释?")
# 打印生成的回复
print(result)