导入本地huggingface的模型:
tokenizer = AutoTokenizer.from_pretrained('./Qwen/Qwen-7B-Chat', trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained('./Qwen/Qwen-7B-Chat', device_map="cuda", trust_remote_code=True).eval()`
使用本地的模型构建pipeline(使用langchain的pipeline模型)
pipe1 = pipeline(
"text2text-generation",
model=model,
tokenizer=tokenizer,
max_length=512,
temperature=0.8,
top_p=0.6,
repetition_penalty=1.5
)
llm = HuggingFacePipeline(pipeline=pipe1)
构建prompt
- 稍微规范一点的方法
首先定义一个template,例如
"""Tell me a story about {heros}"""
再使用template定义一个prompt,
其中如果想简单使用的话可以直接调用
个人理解是会自动分出其中的input但是没法指定output
PromptTemplate.from_template(template = template)
如果想规定多输入输出(链式流水线需要使用)
PromptTemplate(
template = template,
input_variables =["heros","xxx"],
output_variables = {"xxx"},
verbose = True
)
- 不是很规范的方法
其实跟上面是一样的,(直接按照template的格式写进去)
PromptTemplate.from_template(
"""
tell me a story about {heros}
"""
)
构建chain
chain的用处是使用流水线式的大模型链式调用,当然同样可以run或者invoke单一模型
运行单一模型的方式
#方法一
llm.run(prompt.format(heros = "MonkeyKing"))
# 相当于使用llm直接run了tell me a story about MonkeyKing
#----------------------------------------------------------
#方法二(前文已经定义了llm)
chain = LLMChain(llm = llm,prompt = prompt,outputkey = "XXX")
#其中llm和prompt是前文自己定义的,outputkey最好与你的output相同
chain.run(heros = "Monkeyking")
# 看起来这个更麻烦但是chain可以进行多个大模型的链接
简单使用SequentialChain
- 使用SimpleSequentialChain只适合单一输入输出(上一个chain的输出会直接作为下一个chain的输入)(这一部分的template是抄的,自己写的输出太烂了,所以prompt工程值得研究)
from transformers import AutoTokenizer, pipeline
from langchain import HuggingFacePipeline,LLMChain
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain,SimpleSequentialChain
from transformers import AutoModelForCausalLM, AutoTokenizer
import os
os.environ['CUDA_VISIBLE_DEVICES'] ='0'
tokenizer = AutoTokenizer.from_pretrained('./Qwen/Qwen-7B-Chat', trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained('./Qwen/Qwen-7B-Chat', device_map="cuda", trust_remote_code=True).eval()
pipe1 = pipeline(
"text2text-generation",
model=model,
tokenizer=tokenizer,
#max_length=512,
temperature=0.8,
top_p=0.6,
repetition_penalty=1.5
)
pipe2 = pipeline(
"text2text-generation",
model=model,
tokenizer=tokenizer,
#max_length=512,
temperature=0.7,
top_p=1,
repetition_penalty=1.5
)
llm = HuggingFacePipeline(pipeline=pipe1)
llm2 = HuggingFacePipeline(pipeline = pipe2)
template1 = """您是一位剧作家。给定剧本的标题后,您的任务是为该剧本写一个大纲。
标题: {标题}
剧作家: 这是上述剧本的大纲:"""
prompt_template = PromptTemplate(input_variables=["标题"], template=template1)
synopsis_chain = LLMChain(llm=llm, prompt=prompt_template)
template = """您是《纽约时报》的剧评人。给定剧本大纲后,您的任务是为该剧本写一篇评论。
剧本大纲:
{剧本大纲}
《纽约时报》剧评人对上述剧本的评论:"""
prompt_template = PromptTemplate(input_variables=["剧本大纲"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template)
overall_chain = SimpleSequentialChain(
chains=[synopsis_chain, review_chain], verbose=True
)
review = overall_chain.run("夕阳下的海滩悲剧")
- 使用SequentialChain 可以使用多输入输出
from transformers import AutoTokenizer, pipeline
from langchain import HuggingFacePipeline,LLMChain
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain,SequentialChain
from transformers import AutoModelForCausalLM, AutoTokenizer
import os
os.environ['CUDA_VISIBLE_DEVICES'] ='0'
tokenizer = AutoTokenizer.from_pretrained('./Qwen/Qwen-7B-Chat', trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained('./Qwen/Qwen-7B-Chat', device_map="cuda", trust_remote_code=True).eval()
pipe1 = pipeline(
"text2text-generation",
model=model,
tokenizer=tokenizer,
#max_length=512,
temperature=0.8,
top_p=0.6,
repetition_penalty=1.5
)
pipe2 = pipeline(
"text2text-generation",
model=model,
tokenizer=tokenizer,
#max_length=512,
temperature=0.7,
top_p=1,
repetition_penalty=1.5
)
llm = HuggingFacePipeline(pipeline=pipe1)
llm2 = HuggingFacePipeline(pipeline = pipe2)
template = """ 给我讲一个关于{noun}的故事,地点是{position}"""
prompt_te = PromptTemplate.from_template(
template=template
#input_variables=["noun","position"]
)
template2 = """将{story}翻译成英文"""
prompt2_te = PromptTemplate.from_template(
template = template2
)
print(prompt_te.format(noun = "狗",position ="草地上"))
#print(llm.run(prompt.format(noun = "cat",time = "9.00AM")))
chain = LLMChain(llm = llm,prompt = prompt_te,
output_key = "story")
chain2 = LLMChain(llm= llm2,prompt = prompt2_te,
output_key = "translation")
overall_chain = SequentialChain(
chains = [chain,chain2],
input_variables = ["noun","position"],
output_variables = ["story","translation"],
verbose = True )
translation = overall_chain({"noun" : "狗","position" : "草地"})
print(translation)
添加向量知识库
使用训练集微调模型对于新手来说入门难度和上手难度都过高了,使用自建向量数据集可以简单地完成这一任务,我在这里使用的是语言大模型依然是Qwen-7B,编码模型是bge-large-zh中文编码模型,BGE的模型对于中文效果挺好。使用的是huggigface的接口api。
向量数据库使用的是FAISS
from langchain.embeddings import HuggingFaceBgeEmbeddings
from transformers import AutoTokenizer, pipeline
from langchain import HuggingFacePipeline,LLMChain
from langchain.prompts import PromptTemplate
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.chains import LLMChain
from transformers import AutoModelForCausalLM, AutoTokenizer
from langchain.vectorstores import FAISS
from langchain_community.document_loaders import TextLoader
import os
os.environ["HUGGINGFACEHUB_API_TOKEN"] = "hf_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx"
tokenizer = AutoTokenizer.from_pretrained('./Qwen/Qwen-7B-Chat', trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained('./Qwen/Qwen-7B-Chat', device_map="cuda", trust_remote_code=True).eval()
pipe1 = pipeline(
"text2text-generation",
model=model,
tokenizer=tokenizer,
max_length=512,
temperature=0.8,
top_p=0.6,
repetition_penalty=1.5
)
llm = HuggingFacePipeline(pipeline=pipe1)
#llm2=HuggingFaceHub(repo_id="Qwen/Qwen-7B-Chat", model_kwargs={"temperature":0.8, "max_length":512})
model_name = "BAAI/bge-large-zh"
model_kwargs = {'device': 'cpu'}
encode_kwargs = {'normalize_embeddings': True}
hf = HuggingFaceBgeEmbeddings(
model_name=model_name,
model_kwargs=model_kwargs,
encode_kwargs=encode_kwargs
)
loader = TextLoader("elephant.txt")
pages = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=40, chunk_overlap=10)
texts = text_splitter.split_documents(pages)
db = FAISS.from_documents(texts, hf)
query = "大象的孕期是多久?"
docs = db.similarity_search_with_score(query)
print(docs[0])
prompt_te = PromptTemplate.from_template(
"""输入文本:{input_documents}
按照上述文本来回答问题:{question}
最终答案:
"""
)
chain = LLMChain(llm = llm,prompt = prompt_te)
#print(prompt_te)
print(chain.run(input_documents=docs, question=query))
#embedding = hf.embed_query("hi this is harrison")
这两行是必须的,在网站上申请
import os
os.environ["HUGGINGFACEHUB_API_TOKEN"] = "hf_XXXXXXXXXXXXXXXXXX"#你自己的
我使用的文本语料也很简单,只是在百度百科上搜的
大象是长鼻目象科的哺乳动物,有两个属,是世界上最大的陆生动物。其像柱子一样的四肢和宽厚的脚掌可以稳稳支撑住庞大的身体。巨大的头上长有蒲扇状的大耳朵和长且有弹性的鼻子。象耳上有丰富的血管,可以有效散热。鼻子和上唇合而为一的象鼻由超过1.5万块肌肉协调。 [5]
大象分布于撒哈拉以南非洲和亚洲东南部, [8]栖息于多种生存环境,尤喜丛林、草原和河谷地带。群居,雄兽偶有独居。以植物为食,食量大。 [9]大象每隔4-9年产下一仔,孕期20-22个月。 [10]当繁殖期到来,雌象便开始寻找安静僻静之处,用鼻子挖坑,建筑新房,然后摆上礼品。 [11]其寿命长达70年。 [6]
大象非常聪明,具有很高的社会性且善于学习,因此经常被人类驯养。 [7]非洲大陆前几年大象不足70万头,且每年以10%的速度减少,总数很快减少到50万头。出现这种现象的原因是多种多样的,居民人口的迅速增加导致大象栖息地的减少、旱灾、人类偷猎造成的死亡,都在调节着大象的数量。 [12]大象已经被列为世界十大最受贸易活动威胁的物种之一,为了保护濒危大象,肯尼亚等国曾呼吁能够对象牙贸易实施20年的禁令,遏制象牙非法交易,严惩偷猎行为,防止大象灭绝
运行结果如下: