一、基于【文心一言千帆】的指定链接文档langchain问答
1.主要功能
基于给定的 URL ,回答问题。
2.环境构建
需要安装以下库
- langchain
- erniebot
- faiss-cpu
- gradio
- beautifulsoup4
3.效果图
二、ERNIEBOT SDK简介
1.快速安装
执行如下命令,快速安装Python语言的最新版本ERNIE Bot SDK(推荐Python >= 3.8)。
css
pip install --upgrade erniebot
2.快速使用
大家使用ERNIE Bot SDK之前,请首先申请并设置鉴权参数,具体请参考认证鉴权。
** Python接口**
ini
import erniebot
# List supported models
models = erniebot.Model.list()
print(models)
# ernie-bot 文心一言旗舰版
# ernie-bot-turbo 文心一言轻量版
# ernie-text-embedding 文心百中语义模型
# ernie-vilg-v2 文心一格模型
# Set authentication params
erniebot.api_type = "aistudio"
erniebot.access_token = "<access-token-for-aistudio>"
# Create a chat completion
response = erniebot.ChatCompletion.create(model="ernie-bot", messages=[{"role": "user", "content": "你好,请介绍下你自己"}])
print(response.result)
命令行接口(CLI)
ini
# List supported models
erniebot api model.list
# Set authentication params for chat_completion.create
export EB_API_TYPE="aistudio"
export EB_ACCESS_TOKEN="<access-token-for-aistudio>"
# Create a chat completion (using ernie-bot, ernie-bot-turbo, etc.)
erniebot api chat_completion.create --model ernie-bot --message user "请介绍下你自己"
# Set authentication params for image.create
export EB_API_TYPE="yinian"
export EB_ACCESS_TOKEN="<access-token-for-yinian>"
# Generate images via ERNIE-ViLG
erniebot api image.create --model ernie-vilg-v2 --prompt "画一只驴肉火烧" --height 1024 --width 1024 --image-num 1
经典示例
对话补全(Chat Completion)
ERNIE Bot SDK提供具备对话补全能力的文心一言旗舰版模型ernie-bot和文心一言迅捷版模型ernie-bot-turbo。
旗舰版模型的效果更好,迅捷版模型的响应速度更快、推理时延更低,大家可以根据实际场景的需求选择合适的模型。
以下是调用文心一言旗舰版模型进行多轮对话的示例:
ini
import erniebot
erniebot.api_type = "aistudio"
erniebot.access_token = "<access-token-for-aistudio>"
response = erniebot.ChatCompletion.create(
model="ernie-bot",
messages=[{
"role": "user",
"content": "请问你是谁?"
}, {
"role": "assistant",
"content":
"我是百度公司开发的人工智能语言模型,我的中文名是文心一言,英文名是ERNIE-Bot,可以协助您完成范围广泛的任务并提供有关各种主题的信息,比如回答问题,提供定义和解释及建议。如果您有任何问题,请随时向我提问。"
}, {
"role": "user",
"content": "我在深圳,周末可以去哪里玩?"
}])
print(response)
语义向量(Embedding)
ERNIE Bot SDK提供用于提取语义向量的Embedding模型。
该模型基于文心大模型,使用海量数据训练得到,为文心百中系统提供关键能力。该模型可以将字符串转为384维浮点数表达的语义向量,语义向量具备极其精准的语义表达能力,可以用于度量两个字符串之间的语义相似度。
大家可以使用以下代码提取句子的语义向量。
ini
import erniebot
erniebot.api_type = "aistudio"
erniebot.access_token = "<access-token-for-aistudio>"
response = erniebot.Embedding.create(
model="ernie-text-embedding",
input=[
"我是百度公司开发的人工智能语言模型,我的中文名是文心一言,英文名是ERNIE-Bot,可以协助您完成范围广泛的任务并提供有关各种主题的信息,比如回答问题,提供定义和解释及建议。如果您有任何问题,请随时向我提问。",
"2018年深圳市各区GDP"
])
print(response)
大家可以登陆文心百中体验中心,体验更多大模型语义搜索的能力。
文生图(Image Generation)
ERNIE Bot SDK提供具备文生图能力的ERNIE-ViLG大模型。
该模型具备丰富的风格与强大的中文理解能力,支持生成多种尺寸的图片。
ini
import erniebot
erniebot.api_type = "yinian"
erniebot.access_token = "<access-token-for-yinian>"
response = erniebot.Image.create(
model="ernie-vilg-v2",
prompt="雨后的桃花,8k,辛烷值渲染",
width=512,
height=512
)
print(response)
我们推荐两个撰写文生图Prompt提示词的文档,大家可以组合使用,创作出更加精美的图片。
大家也可登陆文心一格平台,体验更多AI艺术与创意辅助的能力。
函数调用(Function Calling)
ERNIE Bot SDK提供函数调用功能,即由大模型根据对话上下文确定何时以及如何调用函数。
借由函数调用,用户可以从大模型获取结构化数据,进而利用编程手段将大模型与已有的内外部API结合以构建应用。
以下是调用文心一言旗舰版模型进行函数调用的示例:
ini
import erniebot
erniebot.api_type = "aistudio"
erniebot.access_token = "<access-token-for-aistudio>"
response = erniebot.ChatCompletion.create(
model="ernie-bot",
messages=[
{
"role": "user",
"content": "深圳市今天气温如何?",
}, ],
functions=[{
"name": "get_current_temperature",
"description": "获取指定城市的气温",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称",
},
"unit": {
"type": "string",
"enum": ["摄氏度", "华氏度"],
},
},
"required": ["location", "unit"],
},
"responses": {
"type": "object",
"properties": {
"temperature": {
"type": "integer",
"description": "城市气温",
},
"unit": {
"type": "string",
"enum": ["摄氏度", "华氏度"],
},
},
},
}, ],
)
print(response)
三、gradio部署
1.安装所需包
python
import os
os.system('pip install langchain')
os.system('pip install erniebot')
os.system('pip install faiss-cpu')
os.system('pip install gradio')
os.system('pip install beautifulsoup4')
import time
# 序列化和反序列化库
import pickle
# 文心一言库
import erniebot
# 进度条库
from tqdm import tqdm
# 文本加载器
from langchain.document_loaders import TextLoader
# 目录加载器
from langchain.document_loaders import DirectoryLoader
# Langchain默认使用的文本切割器,也是Langchain推荐使用的文本切割器
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 相似性搜索库
from langchain.vectorstores.faiss import FAISS
# 泛型库List
from typing import List
# 向量类
from langchain.schema.embeddings import Embeddings
from langchain.document_loaders import WebBaseLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
import textwrap
import langchain
import gradio as gr
2.界面设置
python
# 1.说明
def create_ui_and_launch():
web_dir = 'web'
if not os.path.exists(web_dir):
os.makedirs(web_dir)
with gr.Blocks() as block:
with gr.Row():
gr.Markdown("""# <center> 基于【文心一言千帆】的指定链接文档langchain问答</center>""")
with gr.Row():
gr.HTML(
"""<img align="center" src='https://ai-studio-static-online.cdn.bcebos.com/15fde98025ab4e3ea373f12b209e6904aa88f1a45db440758f69734e763f3be9' width='100%'> <br>""")
with gr.Row():
gr.Markdown("""# 需要安装:
- 1.langchain
- 2.erniebot sdk
- 3.详见 https://cloud.baidu.com/doc/WENXINWORKSHOP/s/wlmhm7vuo
</center>
""")
create_components()
block.queue(api_open=False, concurrency_count=8).launch()
3.输入设置
ini
# 2.输入设置
def create_components():
examples = [["https://zhuanlan.zhihu.com/p/85289282", "明朝的开国皇帝是谁"]]
with gr.Row():
with gr.Row():
with gr.Column(scale=1):
with gr.Accordion(label="基础配置", open=True):
with gr.Group():
access_key = gr.Textbox(
label="access-token-for-aistudio",
info="用于访问aistudio平台的AK",
type='password')
url = gr.Textbox(
label="链接",
info="文章链接")
with gr.Column(scale=3):
output_text = gr.Textbox(label="结 果", placeholder="结果...", lines=3)
question = gr.Textbox(label="消息内容", placeholder="可以对文章进行提问")
with gr.Row():
send_text_btn = gr.Button("🚀发送消息🚀")
regen_btn = gr.Button("✨一键清理✨")
send_text_btn.click(fn=predict, inputs=[access_key, url, question],
outputs=[output_text])
regen_btn.click(fn=lambda value: gr.update(value=""), inputs=regen_btn, outputs=question)
with gr.Row():
gr_examples = gr.Examples(examples=examples, inputs=[url, question],
label="输入示例 (点击选择例子)",
examples_per_page=20)
4.生成库
python
# 3.生成库
def generate_lib(url):
# url="https://zhuanlan.zhihu.com/p/85289282"
loader = WebBaseLoader(url)
data = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=384, chunk_overlap=0,
separators=["\n\n", "\n", " ", "", "。", ","])
docs = text_splitter.split_documents(data)
batch_size = 16
# 块长度
chunk_size = 384
# 向量库
embeddings = []
texts = []
metadatas = []
# 分batch
batch_docs = [docs[i:i + batch_size] for i in range(0, len(docs), batch_size)]
for batch_doc in tqdm(batch_docs):
try:
response = erniebot.Embedding.create(
model='ernie-text-embedding',
input=[item.page_content for item in batch_doc]
)
embeddings += [item['embedding'] for item in response['data']]
texts += [item.page_content for item in batch_doc]
metadatas += [item.metadata for item in batch_doc]
time.sleep(1)
except:
for text in tqdm(batch_doc):
try:
response = erniebot.Embedding.create(
model='ernie-text-embedding',
input=[text.page_content]
)
embeddings.append(response['data'][0]['embedding'])
texts.append(text.page_content)
metadatas.append(text.metadata)
time.sleep(1)
except:
continue
# 组件向量库
data = {
"embeddings": embeddings,
"texts": texts,
'metadatas': metadatas,
}
# 保存向量库
with open(os.path.join('web', 'data.pkl'), 'wb') as f:
pickle.dump(data, f)
5.embedding定义
python
# 4.embeddings
class ErniebotEmbeddings(Embeddings):
def __init__(self, model: str = 'ernie-text-embedding',
batch_size: int = 16, embedding_size: int = 384):
self.model = model
self.batch_size = batch_size
self.embedding_size = embedding_size
def embed_documents(self, texts: List[str]) -> List[List[float]]:
batch_texts = [texts[i: i + self.batch_size]
for i in range(0, len(texts), self.batch_size)]
embeddings = []
for batch_text in tqdm(batch_texts):
try:
response = erniebot.Embedding.create(
model=self.model,
input=batch_text
)
embeddings += [item['embedding'] for item in response['data']]
except:
for text in tqdm(batch_text):
try:
response = erniebot.Embedding.create(
model=self.model,
input=[text]
)
embeddings.append(response['data'][0]['embedding'])
except:
embeddings.append([0.0] * self.embedding_size)
continue
return embeddings
def embed_query(self, text: str) -> List[float]:
response = erniebot.Embedding.create(
model=self.model,
input=[text]
)
return response['data'][0]['embedding']
6.保存知识库
python
# 5.保存知识库
def save_knowledege():
embedding = ErniebotEmbeddings()
with open(os.path.join('web', 'data.pkl'), 'rb') as f:
data = pickle.load(f)
index = FAISS._FAISS__from(
texts=data['texts'], embeddings=data['embeddings'], embedding=embedding, metadatas=data['metadatas']
)
# 保存知识库
index.save_local('web')
7.预测并回答问题
python
# 6.回答
def predict(ak, url, question):
# 设置文心一言鉴权
import erniebot
erniebot.ak = ak
erniebot.type = "aistudio"
# 生成向量库
generate_lib(url)
# 保存知识库
save_knowledege()
embedding = ErniebotEmbeddings()
# 加载知识库
index = FAISS.load_local('web', embedding)
prompt="请根据如下问题和文档给出回答。\n问题:%s\n参考:\n" % question
k = 10
search_type = 'similarity' # mmr
references = []
for i, doc in enumerate(index.search(prompt, k=k, search_type=search_type)):
prompt += '[%d] %s\n%s\n\n' % (i + 1, doc.metadata['source'], doc.page_content)
reference = doc.metadata['source']
if reference not in references:
references.append(reference)
prompt += '\n回答:\n'
response = erniebot.ChatCompletion.create(
model='ernie-bot-4',
messages=[{
'role': 'user',
'content': prompt
}],
stream=True
)
answer=""
for chunk in response:
print(chunk['result'], end='')
answer=answer+chunk['result']
return answer
if __name__ == '__main__':
create_ui_and_launch()