赞
踩
Transformer是几乎所有预训练模型的核心底层架构。基于Transformer预训练所得的大规模语言模型也被叫做“基础模型”(Foundation Model 或Base Model)。
在预训练模型出现的早期,BERT毫无疑问是最具代表性的,也是影响力最大的模型。BERT通过同时学习文本的前向和后向上下文信息,实现对句子结构的深入理解。BERT之后,各种大型预训练模型如雨后春笋般地涌现,自然语言处理(NLP)领域进入了一个新时代。这些模型推动了NLP技术的快速发展,解决了许多以前难以应对的问题,比如翻译、文本总结、聊天对话等等,提供了强大的工具。
大型预训练模型的确是工程师的福音。因为,经过预训练的大模型中所习得的语义信息和所蕴含的语言知识,能够非常容易地向下游任务迁移。NLP应用人员可以对模型的头部或者部分参数根据自己的需要进行适应性的调整,这通常涉及在相对较小的有标注数据集上进行有监督学习,让模型适应特定任务的需求。
预训练模型的微调(Fine-tuning)。微调过程相比于从头训练一个模型要快得多,且需要的数据量也要少得多,这使得作为工程师的我们能够更高效地开发和部署各种NLP解决方案。
这种预训练+微调的大模型应用模式优势明显。首先,预训练模型能够将大量的通用语言知识迁移到各种下游任务上,作为应用人员,我们不需要自己寻找语料库,从头开始训练大模型,这减少了训练时间和数据需求;其次,微调过程可以快速地根据特定任务进行优化,简化了模型部署的难度;最后,预训练+微调的架构具有很强的可扩展性,可以方便地应用于各种自然语言处理任务,大大提高了NLP技术在实际应用中的可用性和普及程度,给我们带来了巨大的便利。
第一步,还是要登录 HuggingFace 网站,并拿到专属于你的Token。
第二步,用 pip install transformers 安装HuggingFace Library。详见这里。
第三步,在命令行中运行 huggingface-cli login,设置你的API Token。
在HuggingFace的Model中,找到 meta-llama/Llama-2-7b。注意,各种各样版本的Llama2模型多如牛毛,我们这里用的是最小的7B版。此外,还有13b\70b\chat版以及各种各样的非Meta官方版。
使用HuggingFace的Transformers库来调用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)
第一种集成方式,是通过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))
这个集成过程非常简单,只需要在HuggingFaceHub类的repo_id中指定模型名称,就可以直接下载并使用模型,模型会自动下载到HuggingFace的Cache目录,并不需要手工下载。
既然HuggingFace Hub还不能完成Llama-2的测试,让我们来尝试另外一种方法,HuggingFace Pipeline。HuggingFace 的 Pipeline 是一种高级工具,它简化了多种常见自然语言处理(NLP)任务的使用流程,使得用户不需要深入了解模型细节,也能够很容易地利用预训练模型来做任务。
# 指定预训练模型的名称 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))
想训练属于自己的模型。而且出于商业秘密的原因,不想开源它,不想上传到HuggingFace,就是要在本机运行模型。此时应该如何利用LangChain的功能?
我们可以创建一个LLM的衍生类,自己定义模型。而LLM这个基类,则位于langchain.llms.base中,通过from langchain.llms.base import LLM语句导入。
这个自定义的LLM类只需要实现一个方法:
以及一个可选方法:
下面,让我们先从HuggingFace的这里,下载一个llama-2-7b-chat.ggmlv3.q4_K_S.bin模型,并保存在本地。
# 导入需要的库 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)
基本上就是CustomLLM类的构建和使用,类内部通过Llama类来实现大模型的推理功能,然后直接返回模型的回答。
除了中文能力不大灵光之外,Llama2的英文表现真的非常完美,和GPT3.5差距不是很大,要知道。
如果你想继续深入学习大模型,那么有几个工具你不得不接着研究。
现在请你再回答一下,什么时候应该使用OpenAI的API?什么时候应该使用开源模型?或者自己开发/微调的模型?
提示:的确,文中没有给出这个问题的答案。因为这个问题并没有标准答案。
请你使用HuggingFace的Transformers库,下载新的模型进行推理,比较它们的性能。
请你在LangChain中,使用HuggingFaceHub和HuggingFace Pipeline这两种接口,调用当前最流行的大语言模型。
提示:HuggingFace Model 页面,有模型下载量的当月排序,当月下载最多的模型就是最流行的模型。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。