使用 Apache Dubbo 释放 DeepSeek R1 的全部潜力

作者:陈子康,Apache Dubbo Contributor

2025年1月20日,国产大模型公司深度求索(DeepSeek)正式发布了大语言模型 DeepSeek-R1,并同步开源其模型权重。通过大规模强化学习技术,DeepSeek-R1 显著提升了推理能力,性能媲美顶尖闭源产品,迅速引发全球关注。用户量以惊人的速度飙升,DeepSeek App 在苹果应用商店中美、英等 157 个国家登顶下载榜,日活量快速突破 2000 万,成为全球增长最快的 APP。

Apache Dubbo 作为一款易用且高性能的分布式服务框架,被广泛应用于构建企业级微服务架构,拥有庞大的用户群体。Dubbo 的多语言生态也十分丰富,支持 Java、Golang、Python、Rust、Node.js 等多种编程语言,为开发者提供了极大的灵活性。

本文将深入探讨如何利用 Dubbo 的多语言 SDK,从大模型的原生部署到将其无缝接入现有业务系统,全面释放 DeepSeek-R1 的潜力,助力 AI 开发的高效落地。

为什么选择本地部署 DeepSeek R1?

  • 目前 DeepSeek 日活量巨大,时常出现“服务器繁忙”的情况。本地部署可以有效避免因服务器负载过高导致的响应延迟或服务中断,确保业务连续性。
  • 本地离线部署能够避免敏感数据上传至云端,降低数据泄露风险,特别适合对数据安全要求较高的个人开发者和企业使用。
  • 本地部署允许用户根据自身需求对 DeepSeek R1 模型进行微调或二次开发,满足特定业务场景的需求。
  • ……

为什么要原生部署 DeepSeek R1?

这里的原生部署指的是使用 DeepSeek 官方仓库 [ 1] 推荐的部署方式进行部署。

在目前关于 DeepSeek 部署的热门文章中,ollama 被广泛推荐为一种快速、轻量的部署工具。对于个人开发者或尝鲜者而言,ollama 的便捷性确实足够。然而,对于大模型开发人员和企业用户来说,ollama 的灵活性和性能存在明显不足。原生部署的核心优势如下:

  1. 灵活性与可扩展性: 原生部署支持对 DeepSeek R1 模型进行任意二次开发,用户可以根据业务需求深度定制模型功能。相比之下,ollama 仅支持有限的微调操作,无法满足复杂的开发需求。
  2. 全精度模型支持: ollama 目前尚不支持全精度的 DeepSeek R1 模型,这可能导致模型性能的损失。而原生部署无此限制,能够充分发挥模型的全部潜力,确保推理精度和效果。

通过原生部署,开发者可以更好地掌控模型的运行环境,优化性能,并为后续的模型迭代和业务集成奠定坚实基础。

原生部署 DeepSeek R1

  • 模型:DeepSeek-R1-Distill-Qwen-7B

  • 模型部署框架:LMDeploy [ 2]
  • 显卡:NVIDIA Corporation GA102GL [A10] (rev a1)

说明: 由于硬件条件限制,本文将使用 DeepSeek R1 的蒸馏版本进行演示,但整体流程适用于其他模型和推理框架。如果需要采用 Docker 等容器化方式部署,请参考 NVIDIA 容器工具包 [ 3] 文档进行相关配置。

基础环境

----------
操作系统:Ubuntu 22.04.5
Python 版本:3.11.10
PyTorch 版本:2.5.1
----------

模型下载

使用 modelscope 提供的 snapshot_download 函数下载模型。其中,第一个参数为模型名称,cache_dir 参数指定模型的下载路径。

from modelscope import snapshot_download

model_dir = snapshot_download('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B', cache_dir='/home/dubbo/model', revision='master')

代码编写

# the path of a model. It could be one of the following options:
# 1. A local directory path of a turbomind model
# 2. The model_id of a lmdeploy-quantized model
# 3. The model_id of a model hosted inside a model repository
model = 'deepseek-ai/DeepSeek-R1-Distill-Qwen-7B'

backend_config = TurbomindEngineConfig(
    cache_max_entry_count=0.2,
    max_context_token_num=20544,
    session_len=20544
)

gen_config = GenerationConfig(
    top_p=0.95,
    temperature=0.6,
    max_new_tokens=8192,
    stop_token_ids=[151329, 151336, 151338],
    do_sample=True  # enable sampling
)

class DeepSeekAiServicer:

    def __init__(self, model: str, backend_config: TurbomindEngineConfig, gen_config: GenerationConfig):
        self.llm = pipeline(model, backend_config=backend_config)
        self.gen_config = gen_config

    def chat(self, content):

        # According to DeepSeek's official recommendations,
        # Each prompt needs to end with <think>\n
        # If it is a mathematical reasoning content, it is recommended to include (in both Chinese and English):
        # Please reason step by step, and put your final answer within \boxed{}.
        prompts = [{
            "role": "user",
            "content": "What is the meaning of life?<think>\n"
            }]

        # Response Example:
        # "<think> The meaning of life is to be happy. </think> I think the meaning of life is to be happy."
        response = self.llm(prompts, gen_config=self.gen_config)
        return response

这样一来,我们就能快速构建、部署和运行 DeepSeek R1,并且还能根据需求灵活地进行二次开发!

利用 Dubbo 多语言 SDK 无成本接入现有业务

使用 Python 对 DeepSeek R1 进行原生部署,使 AI 开发者能够更深入地进行二次开发,最大限度地发挥 DeepSeek R1 的全部潜力。然而,对于国内企业级开发来说,极少有企业会选择 Python 作为业务后端开发语言,更多的是选择性能更佳、Web 生态更成熟的 Java 或 Golang。因此,如何兼顾 AI 模型的开发、部署与现有业务平台的无缝对接,成为企业面临的一大挑战。

近期,Dubbo-Python 发布了 3.0.0b1 [ 4] 版本,支持 Dubbo 3 的核心基础功能。更重要的是,Dubbo-Python 实现了与 Dubbo-Java 的跨语言调用。此功能有效解决了 AI 服务接入现有业务系统的难题。

此外,使用 Dubbo 进行 AI 开发还有以下优点:

  1. 无学习、无接入成本: 大多数推理框架实现的在线服务通常采用 OpenAI 风格或与 Web 框架(如 FastAPI)结合使用。而 Dubbo 提供的跨语言调用方式与同语言直接调用无异,因此用户无需重新学习或适配,便可无缝接入现有系统。
  2. 流式 RPC 调用,支持流式推理: Dubbo 提供丰富且灵活的 RPC 调用方式,包括请求-响应和流式调用。通过流式 RPC 调用结合推理框架的流式推理功能,用户可以在推理过程中实时接收部分结果,避免等待完整推理完成后的长时间延迟,同时规避大文本响应可能引发的一系列风险和问题。

DeepSeek R1 部署(Python 侧)

使用 Dubbo-Python 为 DeepSeek R1 提供服务暴露能力,其模型部署和调用方式与前述代码基本相同,只是将模型推理改为了流式推理,以更好地支持实时响应和大文本输出。

具体代码如下:

"""
The code related to the configuration is the same as above.
"""

class DeepSeekAiServicer:

    def __init__(self, model: str, backend_config: TurbomindEngineConfig, gen_config: GenerationConfig):
        self.llm = pipeline(model, backend_config=backend_config)
        self.gen_config = gen_config

    def chat(self, stream):
        # read request from stream
        request = stream.read()
        print(f"Received request: {request}")
        # prepare prompts
        prompts = [{
            "role": request.role,
            "content": request.content + "<think>\n"
        }]

        is_think = False

        # perform streaming inference
        for item in self.llm.stream_infer(prompts, gen_config=gen_config):
            # update think status
            if item.text == "<think>":
                is_think = True
                continue
            elif item.text == "</think>":
                is_think = False
                continue
            # According to the state of thought, decide the content of the reply.
            if is_think:
                # send thought
                stream.write(chat_pb2.ChatReply(think=item.text, answer=""))
            else:
                # send answer
                stream.write(chat_pb2.ChatReply(think="", answer=item.text))

        stream.done_writing()

def build_server_handler():
    # build a method handler
    deepseek_ai_servicer = DeepSeekAiServicer(model, backend_config, gen_config)
    method_handler = RpcMethodHandler.server_stream(
        deepseek_ai_servicer.chat,
        method_name="chat",
        request_deserializer=chat_pb2.ChatRequest.FromString,
        response_serializer=chat_pb2.ChatReply.SerializeToString,
    )
    # build a service handler
    service_handler = RpcServiceHandler(
        service_name="org.apache.dubbo.samples.llm.api.DeepSeekAiService",
        method_handlers=[method_handler],
    )
    return service_handler

if __name__ == '__main__':
    # build a service handler
    service_handler = build_server_handler()
    service_config = ServiceConfig(service_handler=service_handler)

    # Configure the Zookeeper registry
    registry_config = RegistryConfig.from_url("zookeeper://zookeeper:2181")
    bootstrap = Dubbo(registry_config=registry_config)

    # Create and start the server
    bootstrap.create_server(service_config).start()

    # 30days
    sleep(30 * 24 * 60 * 60)

业务接入(Java 侧)

对于现有的业务平台,无需进行复杂的改动,只需构建一个 Consumer 即可完成服务调用,实现无缝对接。

@Component
public class Consumer implements CommandLineRunner {

    @DubboReference
    private DeepSeekAiService deepSeekAiService;

    @Override
    public void run(String... args) throws Exception {
        ChatRequest request = ChatRequest.newBuilder()
                .setRole("user")
                .setContent("你好,你是谁?你能帮我制定一个dubbo学习计划嘛?")
                .build();

        deepSeekAiService.chat(request, new StreamObserver<ChatReply>() {

            private boolean isThinkPrinted = false;
            private boolean isAnswerPrinted = false;

            @Override
            public void onNext(ChatReply value) {
                printSection("Think", value.getThink(), isThinkPrinted);
                printSection("Answer", value.getAnswer(), isAnswerPrinted);
            }

            @Override
            public void onError(Throwable t) {
                System.err.println("Error received: " + t.getMessage());
                t.printStackTrace();
            }

            @Override
            public void onCompleted() {
                System.out.println("------------ Chat Completed ------------");
            }

            private void printSection(String label, String content, boolean isPrinted) {
                if (!content.isEmpty()) {
                    if (!isPrinted) {
                        System.out.println("------------- " + label + " -------------");
                        if (Objects.equals("Think", label)){
                            isThinkPrinted = true;
                        } else {
                            isAnswerPrinted = true;
                        }
                    }
                    System.out.print(content);
                }
            }
        });
    }
}

总结

本文介绍了如何利用 Apache Dubbo 的多语言 SDK 充分释放 DeepSeek R1 的全部潜力,助力 AI 开发的高效落地。

通过本地部署和原生部署 DeepSeek R1,开发者能够根据业务需求灵活进行模型微调和二次开发,确保业务连续性,同时降低数据泄露风险。

通过 Dubbo 的多语言支持,开发者可以轻松将 DeepSeek R1 接入现有业务系统,实现无缝对接。Dubbo 的流式 RPC 调用功能进一步提升了推理过程的实时响应能力,避免了长时间延迟和大文本响应带来的问题。

总的来说,结合 Dubbo 的多语言 SDK 和 DeepSeek R1 的强大推理能力,开发者可以在保证高性能和高安全性的同时,灵活地进行模型定制和业务集成,为 AI 开发的高效落地提供了强有力的支持。

如果您对 Dubbo 的使用有任何疑问或需要进一步的技术支持,欢迎联系 Dubbo 社区。

Dubbo 社区联系方式:

  • 官网:https://dubbo.apache.org
  • GitHub:https://github.com/apache/dubbo
  • Dubbo Python:https://github.com/apache/dubbo-python
  • 社区交流钉钉群号:105120013829

相关链接:

[1] DeepSeek官方仓库

https://github.com/deepseek-ai

[2] LMDeploy

https://github.com/InternLM/lmdeploy

[3] NVIDIA 容器工具包

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/index.html

[4] 3.0.0b1

https://github.com/apache/dubbo-python/releases/tag/3.0.0b1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/978516.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity TMPro显示中文字体

TMP默认的字体只能显示英语&#xff0c;那么怎么显示中文呢 1、找到支持中文的字体文件 在c盘搜索Fonts文件夹有很多支持中文的字体文件 我这里选择雅黑 PS.双击打开发现里面有粗体细体普通三个版本&#xff0c;也可以只导入一个版本进去 2、将其拖入到unity Assets里面 3…

【MySQL篇】数据库基础

目录 1&#xff0c;什么是数据库&#xff1f; 2&#xff0c;主流数据库 3&#xff0c;MySQL介绍 1&#xff0c;MySQL架构 2&#xff0c;SQL分类 3&#xff0c;MySQL存储引擎 1&#xff0c;什么是数据库&#xff1f; 数据库&#xff08;Database&#xff0c;简称DB&#xf…

Linux 日志系统·

目录 一、前言 二、实现一个简单的日志 1.可变参数 2.日志等级 3.日志时间 4.打印每一条参数 5.合并两个缓冲区 6.封装日志函数 三、完整代码 一、前言 当我们写一个函数&#xff0c;例如打开文件open&#xff0c;当我们打开失败的时候&#xff0c;会调用perror看到错误…

【PromptCoder】使用 package.json 生成 cursorrules

【PromptCoder】使用 package.json 生成 cursorrules 在当今快节奏的开发世界中&#xff0c;效率和准确性至关重要。开发者们不断寻找能够优化工作流程、帮助他们更快编写高质量代码的工具。Cursor 作为一款 AI 驱动的代码编辑器&#xff0c;正在彻底改变我们的编程方式。但如…

【VUE】vue-i18n: Uncaught SyntaxError: Not available in legacy mode

报错&#xff1a; 解决方法&#xff1a; 找到 createI18n 并加上 legacy: false,

2025年SCI一区智能优化算法:混沌进化优化算法(Chaotic Evolution Optimization, CEO),提供MATLAB代码

一、混沌进化优化算法 https://github.com/ITyuanshou/MATLABCode 1. 算法简介 混沌进化优化算法&#xff08;Chaotic Evolution Optimization, CEO&#xff09;是2025年提出的一种受混沌动力学启发的新型元启发式算法。该算法的主要灵感来源于二维离散忆阻映射的混沌进化过…

网络安全之日志审计 网络安全审计制度

一、代码审计安全 代码编写安全: 程序的两大根本:变量与函数 漏洞形成的条件:可以控制的变量“一切输入都是有害的 ” 变量到达有利用价值的函数&#xff08;危险函数&#xff09;“一切进入函数的变量是有害的” 漏洞的利用效果取决于最终函数的功能&#xff0c;变量进入…

VScode+stfp插件,实现文件远程同步保存【2025实操有效】

目录 1 痛点2 准备工作3 操作步骤3.1 第一步&#xff0c;下载STFP插件3.2 第二步&#xff0c;修改配置文件3.3 第三步&#xff0c;测试是否成功 4 后记 1 痛点 我一直用vscode远程连接服务器&#xff0c;传代码文件等到服务器上面&#xff0c;突然有一次服务器那边尽心维修&am…

Java高频面试之SE-23

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; Java 中的 Stream 是 Java 8 引入的一种全新的数据处理方式&#xff0c;它基于函数式编程思想&#xff0c;提供了一种高效、简洁且灵活的方式来…

python-leetcode-乘积最大子数组

152. 乘积最大子数组 - 力扣&#xff08;LeetCode&#xff09; class Solution:def maxProduct(self, nums: List[int]) -> int:if not nums:return 0max_prod nums[0]min_prod nums[0]result nums[0]for i in range(1, len(nums)):if nums[i] < 0:max_prod, min_prod…

NavVis VLX三维扫描:高层建筑数字化的革新力量【沪敖3D】

在三维激光扫描领域&#xff0c;楼梯结构因其复杂的空间形态和连续垂直移动的实际需求&#xff0c;一直是技术难点之一。利用NavVis VLX穿戴式移动扫描系统成功完成一栋34层建筑的高效扫描&#xff0c;其中楼梯部分的数据一遍成形且无任何分层或形变。本文将深入分析该项目的技…

docker安装register私库

一、使用自己的私库 1、安装register私库 docker pull registry运行 docker run -d -v /data/registry:/var/lib/registry -p 5000:5000 --name registry registry:2参数-v /data/registry:/var/lib/registry&#xff0c;挂载目录 2、拉取需要的镜像 docker pull hello-w…

PCI_PCIe子系统学习(一)概念理清

文章目录 1、其它学习文章2、PCI和PCIe总线简单介绍2.1、PCI2.2、PCIe 3、引脚概述3.1、PCI3.1.1、PCI引脚概述3.1.2、PCI引脚定义3.1.2.1、32位 PCI (124针)3.1.2.2、64位 PCI (188针) 3.1.3、PCI引脚功能分类 3.2、PCIe3.2.1、PCIe引脚概述3.2.2、PCIe引脚定义3.2.2.1、PCIe …

解决Deepseek“服务器繁忙,请稍后再试”问题,基于硅基流动和chatbox的解决方案

文章目录 前言操作步骤步骤1&#xff1a;注册账号步骤2&#xff1a;在线体验步骤3&#xff1a;获取API密钥步骤4&#xff1a;安装chatbox步骤5&#xff1a;chatbox设置 价格方面 前言 最近在使用DeepSeek时&#xff0c;开启深度思考功能后&#xff0c;频繁遇到“服务器繁忙&am…

【SpringBoot】——分组校验、自定义注解、登入验证(集成redis)、属性配置方式、多环境开发系统学习知识

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大三学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

TCP/IP 5层协议簇:物理层

目录 1. 物理层&#xff08;physical layer&#xff09; 2. 网线/双绞线 1. 物理层&#xff08;physical layer&#xff09; 工作设备&#xff1a;网线、光纤、空气 传输的东西是比特bit 基本单位如下&#xff1a;数字信号 信号&#xff1a;【模拟信号&#xff08;放大器&a…

【C/C++】理解C++内存与Linux虚拟地址空间的关系---带你通透C++中所有数据

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论&#xff1a; 本质编写的原因是我在复习过程中突然发现虚拟地址空间和C内存划分我好想有点分不清时&#xff0c;进行查询各类资料和整理各类文章后得出的文章&#xff…

(论文)检测部分欺骗音频的初步调查

Paper–An Initial Investigation for Detecting Partially Spoofed Audio 摘要 所有现有的欺骗性语音数据库都包含整个欺骗性的攻击数据。 在实践中&#xff0c;使用仅部分欺骗的话语来装载成功的攻击是完全合理的。根据定义&#xff0c;部分欺骗的话语包含欺骗和真实段的混…

P9420 [蓝桥杯 2023 国 B] 子 2023

P9420 [蓝桥杯 2023 国 B] 子 2023 题目 分析代码 题目 分析 刚拿到这道题&#xff0c;我大脑简单算了一下&#xff0c;这个值太大了&#xff0c;直观感觉就很难&#xff01;&#xff01; 但是&#xff0c;你仔仔细细的一看&#xff0c;先从最简单的第一步入手&#xff0c;再…

第4章 4.4 EF Core数据库迁移 Add-Migration UpDate-Database

4.4.1 数据库迁移原理 总结一下就是&#xff1a; 1. 数据库迁移命令的执行&#xff0c;其实就是生成在数据库执行的脚本代码&#xff08;两个文件&#xff1a;数字_迁移名.cs 数字_迁移名.Designer.cs&#xff09;&#xff0c;用于对数据库进行定义和修饰。 2. 数据库迁移…