当前位置: 首页 > ds >正文

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 torchllm_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 = Nonemodel: AutoModelForCausalLM = Nonedef __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@propertydef _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_contentthink, answer = split_text(response)
print(f"{' - '*20}思考{' - '*20}")
print(think)
print(f"{' - '*20}回答{' - '*20}")
print(answer)

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

http://www.xdnf.cn/news/14522.html

相关文章:

  • Python打卡第54天
  • 13分钟讲解主流Linux发行版
  • origin绘制双Y轴柱状图、双Y轴柱状点线图和双Y轴点线图
  • Node.js验证码:从生成到验证的趣味之旅
  • 条件收敛的级数中项必须趋于 0,正负项抵消,但趋于 0 的速度不需要“足够快”
  • 【学习笔记】深入理解Java虚拟机学习笔记——第9章 类加载及执行子系统的案例与实战
  • 深度学习进化史:从神经元的诞生到万亿参数的觉醒
  • 掌握这些 Python 函数,让你的代码更简洁优雅
  • Git基本使用
  • npm install报错
  • Hudi 与 Hive 集成
  • https说明
  • RV1126+OPENCV对视频流单独进行视频膨胀/腐蚀操作
  • Spring AI 项目实战(八):Spring Boot + AI + DeepSeek 打造企业级智能文档分类系统
  • 40套精品大气黑金系列行业PPT模版分享
  • Web后端基础:数据库
  • 【JavaScript-Day 42】深入解析事件冒泡与捕获:掌握事件委托的精髓
  • 2、Java流程控制:编程界的“逻辑游乐场”
  • Leetcode 刷题记录 12 —— 二叉树第三弹
  • 六月十五号Leetcode
  • Apache Iceberg与Hive集成:非分区表篇
  • 【Redis】分布式锁
  • 我的项目管理之路-PMO
  • OpenSpeedy:让游戏体验“飞”起来的秘密武器
  • 基于CNN深度学习的小程序识别-视频介绍下自取
  • Android 修改了页面的xml布局,使用了databinding,这时候编译时需要用到apt吗
  • Node.js 中两种模块导出方式区别
  • Vue 组合式 API 与 选项式 API 全面对比教程
  • 期权入门介绍
  • PCB设计教程【大师篇】stm32开发板PCB布线(信号部分)