系列篇章💥

No.文章
01【DeepSeek应用实践】DeepSeek接入Word、WPS方法详解:无需代码,轻松实现智能办公助手功能
02【DeepSeek应用实践】通义灵码 + DeepSeek:AI 编程助手的实战指南
03【DeepSeek应用实践】Cline集成DeepSeek:开源AI编程助手,终端与Web开发的超强助力
04【DeepSeek开发入门】DeepSeek API 开发初体验
05【DeepSeek开发入门】DeepSeek API高级开发指南(推理与多轮对话机器人实践)
06【DeepSeek开发入门】Function Calling 函数功能应用实战指南
07【DeepSeek部署实战】DeepSeek-R1-Distill-Qwen-7B:本地部署与API服务快速上手
08【DeepSeek部署实战】DeepSeek-R1-Distill-Qwen-7B:Web聊天机器人部署指南
09【DeepSeek部署实战】DeepSeek-R1-Distill-Qwen-7B:基于vLLM 搭建高性能推理服务器
10【DeepSeek部署实战】基于Ollama快速部署DeepSeek-R1系列模型实战指南(Linux)
11【DeepSeek部署实战】基于Ollama+Chatbox零成本部署DeepSeek-R1系列模型攻略(Windows)
12【DeepSeek开发实战】DeepSeek-R1-Distill-Qwen与LangChain的本地大模型应用开发指南


前言

在大模型应用开发的浪潮中,将强大的大语言模型与灵活的开发框架相结合,能为开发者开启无限可能。本文将详细阐述如何基于DeepSeek-R1-Distill-Qwen大模型与LangChain框架进行本地大模型应用开发,从基础环境搭建到实际应用演示,为你提供全面且深入的指导。无论你是想探索大模型应用开发的新手,还是寻求优化现有项目的资深开发者,都能在本文中找到有价值的内容。

一、环境配置要求

为了高效部署 DeepSeek-R1-Distill-Qwen,推荐使用 Ubuntu 22.04 LTS 操作系统、Python 3.12 环境、CUDA 12.1 与 PyTorch 2.3.0,并配备至少 24GB 显存的 NVIDIA GPU,以确保模型推理的高性能和稳定性。

二、安装相关依赖

# 升级pip并配置清华镜像源
python -m pip install --upgrade pip
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

# 安装依赖包(指定版本)
pip install transformers==4.48.2 \
            huggingface-hub==0.28.1 \
            accelerate==1.3.0 \
            modelscope==1.22.3 \
            langchain==0.3.17

首先,将pip升级到最新版本,这样可以获取pip的最新功能和特性,确保后续依赖包的安装过程更加稳定和高效。接着,将pip源配置为清华大学的镜像源https://pypi.tuna.tsinghua.edu.cn/simple,清华大学的镜像源拥有丰富的资源和快速的下载速度,能够大大缩短依赖包的下载时间。
在这里插入图片描述

三、下载模型文件

from modelscope import snapshot_download
# 下载预训练模型并指定缓存路径
model_dir = snapshot_download('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B', cache_dir='/root/autodl-tmp', revision='master')

在代码中使用modelscope库的snapshot_download函数来下载模型。model_id指定为deepseek-ai/DeepSeek-R1-Distill-Qwen-7B,这是模型在ModelScope平台上的唯一标识符。cache_dir参数指定模型的缓存路径,这里设置为/root/autodl-tmp,用户可以根据自己的实际需求进行修改。revision参数指定模型的版本,master表示使用最新版本。在下载模型时,要确保网络连接稳定,路径设置正确,否则可能会导致下载失败。
在这里插入图片描述

执行上述命令后,模型将开始下载并存储到指定的路径。下载过程可能需要一些时间,具体取决于网络速度和模型大小。在下载完成后,模型就可以用于后续的应用开发了。

四、LangChain自定义LLM类实现

创建LLM.py 文件实现模型接入:

from langchain.llms.base import LLM
from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
import torch

class DeepSeek_R1_Distill_Qwen_LLM(LLM):
    # 基于本地 DeepSeek_R1_Distill_Qwen 自定义 LLM 类
    tokenizer: AutoTokenizer = None
    model: AutoModelForCausalLM = None
      
    def __init__(self, mode_name_or_path :str):

        super().__init__()
        print("正在从本地加载模型...")
        self.tokenizer = AutoTokenizer.from_pretrained(mode_name_or_path, use_fast=False)
        self.model = AutoModelForCausalLM.from_pretrained(mode_name_or_path, torch_dtype=torch.bfloat16, device_map="auto")
        self.model.generation_config = GenerationConfig.from_pretrained(mode_name_or_path)
        print("完成本地模型的加载")
      
    def _call(self, prompt : str, stop: Optional[List[str]] = None,
                run_manager: Optional[CallbackManagerForLLMRun] = None,
                **kwargs: Any):

        messages = [{"role": "user", "content": prompt }]
        input_ids = self.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
        model_inputs = self.tokenizer([input_ids], return_tensors="pt").to('cuda')
        generated_ids = self.model.generate(model_inputs.input_ids, attention_mask=model_inputs['attention_mask'], max_new_tokens=8192) # 思考需要输出更多的Token数,设为8K
        generated_ids = [
            output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
        ]
        response = self.tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
      
        return response
    @property
    def _llm_type(self) -> str:
        return "DeepSeek_R1_Distill_Qwen_LLM"

LLM.py文件中,定义了一个自定义的DeepSeek_R1_Distill_Qwen_LLM类,它继承自langchain.llms.base中的LLM类。在__init__方法中,初始化了模型的分词器和模型本体,设置了模型的数据类型为torch.bfloat16,并自动分配设备。_call方法则实现了模型的推理过程,接收用户的提示词,经过一系列处理后,返回模型生成的回答。_llm_type属性则返回模型的类型,用于标识自定义的模型。

五、应用实例演示

1. LLM体验测试

from LLM import DeepSeek_R1_Distill_Qwen_LLM
llm = DeepSeek_R1_Distill_Qwen_LLM(mode_name_or_path = "/root/autodl-tmp/deepseek-ai/DeepSeek-R1-Distill-Qwen-7B")

response = llm("你是谁?")
response

代码执行如下:
在这里插入图片描述

2. 内容分割测试

将模型的回答解析为思考过程和最终回答

import re

text = '''您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。
</think>

您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。'''

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

if match:
    print("匹配成功!")
    print("捕获组1:", match.group(1))  # <think>...</think>之间的内容
    print("捕获组2:", match.group(2))  # </think>之后的内容
else:
    print("匹配失败!")

测试如下:
在这里插入图片描述

3. 封装split_text方法

接下来,我们通过split_text方法将模型的回答解析为思考过程和最终回答,分别进行打印展示。

import re

# 文本分割函数
def split_text(text):
    #pattern = re.compile(r'<think>(.*?)</think>(.*)', re.DOTALL) # 定义正则表达式模式
    pattern = re.compile(r'(.*?)</think>(.*)', re.DOTALL)
    match = pattern.search(text) # 匹配 <think>思考过程</think>回答
  
    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

response = llm("你是谁?")

think, answer = split_text(response)

print(f"{'-'*20} 思考过程 {'-'*20}")
print(think)
print(f"\n{'-'*20} 最终回答 {'-'*20}")
print(answer)

打印结果如下:

-------------------- 思考过程 --------------------
您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。

-------------------- 最终回答 --------------------
您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。

4. 深度思考提问

response = llm("我有6个苹果,吃了1个,送给了你2个,掉3个还剩多少个?")
think, answer = split_text(response)

print(f"{'-'*20} 思考过程 {'-'*20}")
print(think)
print(f"\n{'-'*20} 最终回答 {'-'*20}")
print(answer)

打印结果如下:

-------------------- 思考过程 --------------------
首先,我有6个苹果。

我吃掉了1个苹果,剩下5个。

然后,我送了你2个苹果,剩下3个。

接着,苹果掉了3个,所以剩下的苹果数量减少了3个。

最后,我剩下0个苹果。

-------------------- 最终回答 --------------------
**解答:**

1. **初始苹果数量:**
   \[
   6 \text{个}
   \]

2. **吃掉1个苹果:**
   \[
   6 - 1 = 5 \text{个}
   \]

3. **送给对方2个苹果:**
   \[
   5 - 2 = 3 \text{个}
   \]

4. **苹果掉落地掉3个:**
   \[
   3 - 3 = 0 \text{个}
   \]

**最终剩下的苹果数量:**
\[
\boxed{0}
\]

六、常见问题

1. 路径配置问题

需确保cache_dirmode_name_or_path参数指向正确的本地路径。路径配置错误可能导致模型无法正确下载或加载,从而使应用无法正常运行。在设置路径时,要仔细检查路径的准确性,包括目录结构和文件名的拼写。

2. CUDA内存不足

可尝试降低max_new_tokens参数值或使用低精度模式。当模型在推理过程中出现CUDA内存不足的情况时,说明当前的参数设置超出了GPU的内存承受能力。降低max_new_tokens参数值可以减少模型生成的文本长度,从而降低内存需求。使用低精度模式,如torch.bfloat16,可以在一定程度上减少内存占用,提高模型的运行效率。

3. 环境依赖冲突

建议使用我们提供的预配置镜像环境。环境依赖冲突是开发过程中常见的问题,不同库之间的版本兼容性可能会导致各种错误。使用预配置的镜像环境可以避免这些问题,因为镜像环境已经经过测试和优化,确保了各个依赖库之间的兼容性。

结语

本文完整地实现了DeepSeek-R1大模型的本地部署与LangChain框架的集成,为开发者提供了一个坚实的基础。在此基础上,开发者可以快速构建如RAG应用、智能助手等各种AI应用。在开发过程中,遇到问题不要气馁,多参考文档和社区资源,相信你一定能创造出令人惊艳的大模型应用。欢迎在评论区分享你的开发经验和遇到的问题,让我们一起交流进步!

在这里插入图片描述

🎯🔖更多专栏系列文章:AI大模型提示工程完全指南AI大模型探索之路(零基础入门)AI大模型预训练微调进阶AI大模型开源精选实践AI大模型RAG应用探索实践🔥🔥🔥 其他专栏可以查看博客主页📑

😎 作者介绍:资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索(CSDN博客之星|AIGC领域优质创作者)
📖专属社群:欢迎关注【小兵的AI视界】公众号或扫描下方👇二维码,回复‘入群’ 即刻上车,获取邀请链接。
💘领取三大专属福利:1️⃣免费赠送AI+编程📚500本,2️⃣AI技术教程副业资料1套,3️⃣DeepSeek资料教程1套🔥(限前500人)
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我们,一起携手同行AI的探索之旅,开启智能时代的大门!

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐