LangChain调用本地modelscope下载的Deepseek大模型

langChain通常使用api接口来调用大模型,可以直接访问官方的服务器或者用Ollama等搭建的本地服务器。langchain访问modelscope的官方服务可参照ModelScope | 🦜️🔗 LangChain

现在我们调用的是 modelscope上下载的用DeepSeek,由于本地显卡运算能力有限选用deepseek蒸馏出来的Qwen1.5B deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B


snapshot_download(llm_model_name, cache_dir=cache_apath)下载大模型到本地cache并返回大模型的路径

需要设计自己的类(基类为LLM),至少拥有3个函数__init__、_call、_llm_type

__init__:指定tokenizer和llm model

_call:对message进行tokenizer,输入大模型来生成响应,对生成的向量进行解码

_llm_type:给一个名字

import os
from langchain_core.prompts import PromptTemplate
from langchain.llms.base import LLM
from typing import Any, List, Optional
from modelscope import snapshot_download
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
import torch

llm_model_name = "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B"
cache_apath = os.path.join(os.getcwd(), 'cache')
# llm_model_path = snapshot_download(llm_model_name, cache_dir=cache_apath)
llm_model_path = os.path.join(cache_apath, *llm_model_name.replace(".","___").split('/'))

class DeepSeekQwenLLM(LLM):
    tokenizer: AutoTokenizer = None
    model: AutoModelForCausalLM = None

    def __init__(self, model_path: str):
        super().__init__()
        print("Loading model from local path...")
        self.tokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=False)
        self.model = AutoModelForCausalLM.from_pretrained(model_path, torch_dtype=torch.bfloat16, device_map="auto")
        self.model.generation_config = GenerationConfig.from_pretrained(model_path)
        print("Model loading complete.")

    def _call(self, prompt: str, stop: Optional[List[str]] = None,
              run_manager: Optional[CallbackManagerForLLMRun] = None,
              **kwargs: Any) -> str:
        messages = [{"role": "user", "content": prompt}]
        input_text = self.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
        model_inputs = self.tokenizer([input_text], return_tensors="pt").to('cuda')
        output_ids = self.model.generate(model_inputs.input_ids, attention_mask=model_inputs['attention_mask'],
                                         max_new_tokens=8192)
        generated_ids = [ids[len(input_text):] for ids in output_ids]
        response = self.tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

        return response

    @property
    def _llm_type(self) -> str:
        return "DeepSeekQwenLLM"

按照chain的方法,进行调用

llm_model = DeepSeekQwenLLM(llm_model_path)
template = '''
#背景信息#
你是一名知识丰富的导航助手,了解中国每一个地方的名胜古迹及旅游景点.
#问题#
游客:我是{本人的描述},我想去旅游,给我推荐{地方}十个值得玩的地方?"
'''
prompt = PromptTemplate(
    input_variables=["本人的描述", "地方"],
    template=template
)

chain = prompt | llm_model
response = chain.invoke({"本人的描述":"外国的小学生,喜欢室外活动", "地方":"武汉"} )
print(response)


import re
def split_text(text):
    pattern = re.compile(r'(.*?)</think>(.*)', re.DOTALL)
    match = pattern.search(text)

    if match:
        think_content = match.group(1).strip()
        answer_content = match.group(2).strip()
    else:
        think_content = ""
        answer_content = text.strip()

    return think_content, answer_content

think, answer = split_text(response)
print(f"{' - '*20}思考{' - '*20}")
print(think)
print(f"{' - '*20}回答{' - '*20}")
print(answer)

另外说明一下:ollama对各个大模型的支持已经很好,langchain有langchain-ollama的包,通过ollama调用大模型更加方便,不必像上面这么麻烦。当然llama-index也是不错的选择

### 如何使用 LangChain4j 调用 DeepSeek 大模型 #### 1. 注册火山引擎账号并获取 API Key 为了调用火山引擎上的 DeepSeek 模型,首先需要注册火山引擎账号,并完成身份认证流程。登录后进入控制台页面,找到 **API 管理** 或者类似的选项,生成专属的 API Key[^2]。 #### 2. 添加 Maven 依赖配置 LangChain4j 是 Java 版本的 LangChain 框架,支持多种大语言模型的集成。在项目中引入 LangChain4j 和相关依赖项时,需编辑 `pom.xml` 文件,添加如下内容: ```xml <dependencies> <!-- LangChain4j Core --> <dependency> <groupId>com.langchain4j</groupId> <artifactId>langchain4j-core</artifactId> <version>0.9.0</version> </dependency> <!-- Volcano Engine DeepSeek Integration --> <dependency> <groupId>com.volcengine</groupId> <artifactId>volc-sdk-java</artifactId> <version>1.7.0</version> </dependency> </dependencies> ``` 上述代码片段展示了如何通过 Maven 构建工具来管理项目的依赖关系。 #### 3. 初始化 DeepSeek 模型对象 加载 DeepSeek 的具体实现可以通过 LangChain4j 提供的标准接口完成。以下是初始化模型的一个简单例子: ```java import com.langchain4j.llm.VolcanoEngineDeepSeek; import com.langchain4j.LLM; public class Main { public static void main(String[] args) { String apiKey = "your-volcano-engine-api-key"; // 替换为实际的 API 密钥 LLM model = new VolcanoEngineDeepSeek(apiKey); System.out.println(model.generate("你好,世界")); } } ``` 此部分实现了对 DeepSeek 模型的基本封装和调用逻辑。 #### 4. 构建本地知识库用于 RAG 应用场景 如果目标是构建检索增强生成 (RAG) 系统,则还需要额外设置一个向量数据库作为存储结构化的文档数据源。可以采用 Milvus 或 Pinecone 这样的第三方服务,或者利用 Hugging Face Datasets 工具集预处理自有资料集合。 假设已经准备好了一个小型的知识库文件夹路径 `/path/to/knowledgebase/` ,那么可以用下面的方式将其嵌入到工作流里: ```java import com.langchain4j.retriever.VectorStoreRetriever; import com.langchain4j.vectorstore.MilvusVectorStore; // 创建向量存储实例 MilvusVectorStore vectorStore = new MilvusVectorStore( "localhost", 19530, "default" ); // 加载已有索引或新建索引 vectorStore.load("/path/to/index"); // 设置检索器参数 VectorStoreRetriever retriever = new VectorStoreRetriever(vectorStore, 5); // 返回前五个最相似的结果 ``` 以上代码说明了如何连接至 Milvus 向量数据库,并定义好查询返回条目的数量限制。 #### 5. 执行完整的 RAG 流程 最后一步就是把前面提到的所有组件串联起来形成闭环的应用程序架构。当接收到用户的提问请求之后,先经过检索阶段找出关联度最高的几篇参考资料摘要;再把这些上下文信息传递给大型语言模型去综合分析作答即可得到最终回复结果。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值