在实际应用过程中,我们经常会部署开源的大模型并将其定义成服务接口,或者做成web页面的形式,这样就能使用和测试大模型的推理能力。我们在使用kimi,千问,deepseek时会发现他们都有一个联网功能,大模型增加了联网搜索功能后,能够实时为大模型提供推理所需的素材,减少大模型的幻觉,提供大模型的推理准确性。
离线的大模型可以通过搜索接口实现联网搜索功能,常用的搜索引擎几乎都会提供API接口,其中倍受推荐的是tavily
,但这些API接口都是收费的,本文使用DuckDuckGo
来实现离线大模型的联网搜索功能,DuckDuckGo
的好处就是免费。
1.启动虚拟环境
根据自己的实际情况启动运行大模型的虚拟环境,在本例中我使用了千问的模型,所以在我的测试服务器上我使用以下命令启动了千问的虚拟环境。
conda activate qwen
2.安装依赖
pip install -qU langchain-openai
pip install -qU langchain-anthropic
pip install -qU langchain_community
pip install -qU langchain_experimental
pip install -qU langgraph
pip install -qU duckduckgo-search
📓 如果你使用kaggle的notebook环境,还需要安装accelerate
和ipywidgets
。
3.代码示例
3.1 大模型不联网的示例
import os
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
from langchain_core.prompts import ChatPromptTemplate
# 设置模型标识符或本地模型目录
model_dir = "Qwen/Qwen2-7B-Instruct"
# 加载分词器和模型
tokenizer = AutoTokenizer.from_pretrained(model_dir, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_dir,
return_dict=True,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True,
)
# 使用 transformers 的 pipeline 初始化聊天模型
chat = pipeline('text-generation', model=model, tokenizer=tokenizer)
# 定义聊天提示模板(只包含系统提示和用户输入)
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
("user", "{input}")
])
# 创建一个提问和生成回答的链
def chain(input_text):
# 格式化提示模板,将用户输入填入
prompt_text = prompt.format(input=input_text)
# 使用模型生成回复
response = chat(prompt_text, max_length=512, num_return_sequences=1)
return response[0]['generated_text']
# 示例用法
response = chain("青岛今天的天气如何")
print(response)
运行上面的代码后,会出现如下的输出,说明大模型并没有联网功能。
3.2 大模型联网后的示例
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 初始化 DuckDuckGoSearchRun 工具
search_tool = DuckDuckGoSearchRun()
# 初始化模型
import os
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
# 设置模型保存路径
model_dir = './Qwen2-7B-Instruct'
# 如果模型目录不存在,则下载并保存模型
if not os.path.exists(model_dir):
os.makedirs(model_dir)
base_model = "Qwen/Qwen2-7B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(base_model)
tokenizer.save_pretrained(model_dir)
model = AutoModelForCausalLM.from_pretrained(
base_model,
return_dict=True,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True,
)
model.save_pretrained(model_dir)
else:
tokenizer = AutoTokenizer.from_pretrained(model_dir)
model = AutoModelForCausalLM.from_pretrained(
model_dir,
return_dict=True,
low_cpu_mem_usage=True,
torch_dtype=torch.float16,
device_map="auto",
trust_remote_code=True,
)
# 初始化聊天模型
chat = pipeline('text-generation', model=model, tokenizer=tokenizer)
# 为聊天机器人定义一个提示模板
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant. Use the search tool to find up-to-date information if needed."),
("user", "{input}"),
("assistant", "{search_results}"),
])
# 创建一个集成搜索工具和 LLM(大型语言模型)的链
def chain(input_text):
# 获取搜索结果
search_results = search_tool.invoke({'query': input_text})
# 将搜索结果和用户输入整合到提示模板中
prompt_text = prompt.format(input=input_text, search_results=search_results)
# 生成响应
response = chat(prompt_text, max_length=512, num_return_sequences=1)
return response[0]['generated_text']
# 示例用法
response = chain("青岛今天的天气如何")
print(response)
运行上面的代码后,会输出如下图所示的输出,说明模型具备了联网的功能。
👿 由于duckduckgo需要梯子才能使用,所以上面的示例要有科学上网的环境才行。