昇思+昇騰開發板:DeepSeek-R1-Distill-Qwen-1.5B 模型推理部署與 JIT 優化實踐

目錄

引言

模型推理部署

環境準備

安裝 MindSpore

?查看當前 mindspore 版本

安裝 MindNLP

模型與分詞器加載

導入必要的庫

加載分詞器

加載模型

對話功能實現

設置系統提示詞

構建對話歷史輸入

推理函數實現

交互界面實現

推理JIT優化

????????基礎環境安裝

JIT 優化配置

核心優化組件實現

Top-p 采樣函數

模型加載與 JIT 化

JIT 加速的推理函數

自回歸生成與優化效果驗證

靜態緩存與生成流程

優化效果測試


引言


????????本文將詳細介紹如何對 DeepSeek-R1-Distill-Qwen-1.5B 模型進行推理部署,構建可交互的對話機器人,并利用 MindSpore 的 JIT(Just-In-Time)編譯技術進行推理優化,以提升模型的響應速度和用戶體驗。本教程適用于昇思大模型平臺的單卡環境,相關操作在昇騰開發板上的實際應用可參考示例代碼。

模型推理部署


環境準備

????????在進行模型部署前,需要先配置合適的運行環境,主要包括安裝指定版本的 MindSpore 深度學習框架和 MindNLP 自然語言處理工具庫。

安裝 MindSpore

????????MindSpore 是華為推出的開源深度學習框架,本教程使用 2.6.0 版本,安裝命令如下:

%%capture captured_output
# 實驗環境已經預裝了mindspore==2.6.0,如需更換mindspore版本,可更改下面 MINDSPORE_VERSION 變量
!pip uninstall mindspore -y
%env MINDSPORE_VERSION=2.6.0
!pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/${MINDSPORE_VERSION}/MindSpore/unified/aarch64/mindspore-${MINDSPORE_VERSION}-cp39-cp39-linux_aarch64.whl --trusted-host ms-release.obs.cn-north-4.myhuaweicloud.com -i https://pypi.tuna.tsinghua.edu.cn/simple

?查看當前 mindspore 版本

# 查看當前 mindspore 版本
!pip show mindspore

運行結果:

Name: mindspore
Version: 2.6.0
Summary: MindSpore is a new open source deep learning training/inference framework that could be used for mobile, edge and cloud scenarios.
Home-page: https://www.mindspore.cn
Author: The MindSpore Authors
Author-email: contact@mindspore.cn
License: Apache 2.0
Location: /home/mindspore/miniconda/envs/jupyter/lib/python3.9/site-packages
Requires: asttokens, astunparse, dill, numpy, packaging, pillow, protobuf, psutil, safetensors, scipy
Required-by: mindnlp

安裝 MindNLP

????????MindNLP 是基于 MindSpore 的自然語言處理庫,提供了豐富的預訓練模型和處理工具,本教程使用 0.4.1 版本:

%%capture captured_output
# 安裝mindnlp 0.4.1 版本
!pip uninstall mindnlp -y
!pip install https://xihe.mindspore.cn/coderepo/web/v1/file/MindSpore/mindnlp/main/media/mindnlp-0.4.1-py3-none-any.whl

模型與分詞器加載

????????環境配置完成后,需要加載 DeepSeek-R1-Distill-Qwen-1.5B 模型及其對應的分詞器。

導入必要的庫

from mindnlp.transformers import AutoModelForCausalLM, AutoTokenizer
from mindnlp.transformers import TextIteratorStreamer
from mindnlp.peft import PeftModel
from threading import Thread

運行結果:

加載分詞器

????????分詞器的作用是將自然語言文本轉換為模型可理解的 token 序列:


# 開啟同步,在出現報錯,定位問題時開啟
# mindspore.set_context(pynative_synchronize=True)# Loading the tokenizer and model from Modelers's model hub.
tokenizer = AutoTokenizer.from_pretrained("MindSpore-Lab/DeepSeek-R1-Distill-Qwen-1.5B-FP16", mirror="modelers")
# 設置pad_token為eos_token
if tokenizer.pad_token is None:tokenizer.pad_token = tokenizer.eos_token

? 運行結果:

加載模型

????????使用 AutoModelForCausalLM 加載預訓練的因果語言模型:

model = AutoModelForCausalLM.from_pretrained("MindSpore-Lab/DeepSeek-R1-Distill-Qwen-1.5B-FP16", mirror="modelers")
# adapter_model path
# model = PeftModel.from_pretrained(model, "./output/DeepSeek-R1-Distill-Qwen-1.5B/adapter_model_for_demo/")

????????加載過程中可能會出現一些警告信息,如關于模型未繼承 GenerationMixin 類和滑動窗口注意力機制的提示,這些通常不影響基本功能的使用。

運行結果:

對話功能實現

????????為了實現與用戶的交互,需要構建處理對話歷史、生成模型響應的相關函數。

設置系統提示詞

????????系統提示詞用于定義模型的行為和角色:

system_prompt = "你是一個智能聊天機器人,以最簡單的方式回答用戶問題"

構建對話歷史輸入

????????該函數將歷史對話和當前用戶輸入整理成模型所需的格式:

def build_input_from_chat_history(chat_history, msg: str):messages = [{'role': 'system', 'content': system_prompt}]for info in chat_history:role, content = info['role'], info['content']messages.append({'role': role, 'content': content})messages.append({'role': 'user', 'content': msg})return messages

推理函數實現

????????推理函數負責將用戶輸入轉換為模型輸入,調用模型生成響應,并處理流式輸出:

def inference(message, history):messages = build_input_from_chat_history(history, message)input_ids = tokenizer.apply_chat_template(messages,add_generation_prompt=True,return_tensors="ms",tokenize=True)streamer = TextIteratorStreamer(tokenizer, timeout=300, skip_prompt=True, skip_special_tokens=True)generate_kwargs = dict(input_ids=input_ids,streamer=streamer,max_new_tokens=1024,use_cache=True,)t = Thread(target=model.generate, kwargs=generate_kwargs)t.start()  # Starting the generation in a separate thread.partial_message = ""for new_token in streamer:partial_message += new_tokenprint(new_token, end="", flush=True)messages.append({'role': 'assistant', 'content': partial_message})return messages[1:]

交互界面實現

????????為了方便用戶使用,構建一個簡單的命令行交互界面:

import os
import platformos_name = platform.system()
clear_command = 'cls' if os_name == 'Windows' else 'clear'
welcome_prompt = '歡迎使用 DeepSeek-R1-Distill-Qwen-1.5B 模型,輸入內容即可進行對話,clear 清空對話歷史,stop 終止程序'
print(welcome_prompt)
history = []
while True:query = input("\n用戶:")if query.strip() == "stop":breakif query.strip() == "clear":os.system(clear_command)print(welcome_prompt)continueprint("\nDeepSeek-R1-Distill-Qwen-1.5B:", end="")history = inference(query, history)print("")

運行結果:

輸入框中輸入:qianduanjidi回車

推理JIT優化


????????在大語言模型的實際應用中,推理速度直接影響用戶體驗。本文將詳細介紹如何基于 MindSpore 框架的 JIT(Just-In-Time)編譯技術,對 DeepSeek-R1-Distill-Qwen-1.5B 模型進行推理優化,通過降低單次推理耗時提升對話響應速度。

????????基礎環境安裝

????????JIT 優化依賴特定版本的 MindSpore 和 MindNLP,需先完成環境配置:

# 卸載現有MindSpore版本
!pip uninstall mindspore -y
# 指定MindSpore版本為2.6.0并安裝
%env MINDSPORE_VERSION=2.6.0
!pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/${MINDSPORE_VERSION}/MindSpore/unified/aarch64/mindspore-${MINDSPORE_VERSION}-cp39-cp39-linux_aarch64.whl --trusted-host ms-release.obs.cn-north-4.myhuaweicloud.com -i https://pypi.tuna.tsinghua.edu.cn/simple# 安裝適配的MindNLP 0.4.1版本
!pip uninstall mindnlp -y
!pip install https://xihe.mindspore.cn/coderepo/web/v1/file/MindSpore/mindnlp/main/media/mindnlp-0.4.1-py3-none-any.whl

????????安裝完成后,可通過pip show mindspore確認版本為 2.6.0,確保環境一致性。

JIT 優化配置

????????MindSpore 的 JIT 編譯需要通過set_context進行參數配置,開啟圖算融合和指定優化級別:

import mindspore
from mindnlp.transformers import AutoTokenizer, AutoModelForCausalLM, StaticCache
from mindnlp.core import ops
from mindnlp.configs import set_pyboost
import time
import numpy as np# 開啟O2級別的jit優化,開啟圖算融合
mindspore.set_context(enable_graph_kernel=True,mode=mindspore.GRAPH_MODE,jit_config={"jit_level": "O2",},
)

運行結果:

核心優化組件實現

Top-p 采樣函數

????????采樣環節是生成式模型的關鍵步驟,為提升效率,采用基于 NumPy 的實現(在邊緣設備如香橙派上表現更優):

def sample_top_p(probs, p=0.9):"""Top-p采樣函數,用于生成文本時選擇下一個token。此處優先采用基于numpy而不是原生MindSpore的實現方式,因為在香橙派上運行效率更高"""probs_np = probs.asnumpy()# 按概率降序排序sorted_indices = np.argsort(-probs_np, axis=-1)sorted_probs = np.take_along_axis(probs_np, sorted_indices, axis=-1)# 計算累積概率并創建掩碼cumulative_probs = np.cumsum(sorted_probs, axis=-1)mask = cumulative_probs - sorted_probs > psorted_probs[mask] = 0.0sorted_probs = sorted_probs / np.sum(sorted_probs, axis=-1, keepdims=True)# 轉換回MindSpore Tensorsorted_probs_tensor = mindspore.Tensor(sorted_probs, dtype=mindspore.float32)sorted_indices_tensor = mindspore.Tensor(sorted_indices, dtype=mindspore.int32)next_token_idx = ops.multinomial(sorted_probs_tensor, 1)batch_size = probs.shape[0]batch_indices = ops.arange(0, batch_size, dtype=mindspore.int32).reshape(-1, 1)# 此處采用基于mindspore.ops的實現方式,在香橙派上兼容性最好# next_token = sorted_indices_tensor[batch_indices, next_token_idx]next_token = mindspore.ops.gather(sorted_indices_tensor, next_token_idx, axis=1, batch_dims=1)# next_token = mindspore.mint.gather(sorted_indices_tensor, dim=1, index=next_token_idx)return next_token

模型加載與 JIT 化

????????加載模型并通過model.jit()實現全圖靜態化,為編譯優化奠定基礎:

# 該任務將使用DeepSeek-R1-Distill-Qwen-1.5B模型,對給定的prompt進行補齊
prompts = ["請介紹一下自己。<think>","My favorite all time favorite condiment is ketchup.",
]# 生成參數配置
NUM_TOKENS_TO_GENERATE = 40  # 每個輸入要生成的token數量
TEMPERATURE = 0.8            # 溫度參數(控制生成多樣性)
TOP_P = 0.8                  # Top-p采樣閾值model_id = "MindSpore-Lab/DeepSeek-R1-Distill-Qwen-1.5B-FP16"
tokenizer = AutoTokenizer.from_pretrained(model_id, mirror="modelers")
model = AutoModelForCausalLM.from_pretrained(model_id, low_cpu_mem_usage=True, mirror="modelers")# 使用model.jit()將全圖靜態圖化
model.jit()inputs = tokenizer(prompts, return_tensors="ms", padding=True)
set_pyboost(False)

運行結果:

JIT 加速的推理函數

????????通過@mindspore.jit裝飾器對核心推理函數進行編譯優化,減少重復計算開銷:

# 使用@mindspore.jit裝飾器封裝模型推理函數
@mindspore.jit(jit_config=mindspore.JitConfig(jit_syntax_level='STRICT'))
def get_decode_one_tokens_logits(model, cur_token, input_pos, cache_position, past_key_values, temperature=TEMPERATURE, top_p=TOP_P):"""單個token的解碼函數,返回logits,可以使用jit進行優化"""logits = model(cur_token,position_ids=input_pos,cache_position=cache_position,past_key_values=past_key_values,return_dict=False,use_cache=True)[0]return logits
def decode_one_tokens(model, cur_token, input_pos, cache_position, past_key_values, temperature=TEMPERATURE, top_p=TOP_P):"""單個token的解碼函數,由logits、溫度和Top_p選擇合適的token"""logits = get_decode_one_tokens_logits(model, cur_token, input_pos, cache_position, past_key_values, temperature, top_p)if temperature > 0:probs = mindspore.mint.softmax(logits[:, -1] / temperature, dim=-1)new_token = sample_top_p(probs, top_p)else:new_token = mindspore.mint.argmax(logits[:, -1], dim=-1)[:, None]return new_token

自回歸生成與優化效果驗證

靜態緩存與生成流程

????????使用StaticCache緩存注意力計算結果,減少自回歸生成中的重復計算:

batch_size, seq_length = inputs["input_ids"].shape# 創建靜態緩存(用于加速自回歸生成)
past_key_values = StaticCache(config=model.config, max_batch_size=2, max_cache_len=512, dtype=model.dtype
)
cache_position = ops.arange(seq_length)
generated_ids = ops.zeros(batch_size, seq_length + NUM_TOKENS_TO_GENERATE + 1, dtype=mindspore.int32
)
generated_ids[:, cache_position] = inputs["input_ids"].to(mindspore.int32)# 初始前向傳播獲取首個logits
logits = model(**inputs, cache_position=cache_position, past_key_values=past_key_values,return_dict=False, use_cache=True
)[0]

優化效果測試

????????通過循環生成并記錄單步耗時,驗證 JIT 優化效果:

# 生成第一個新token
if TEMPERATURE > 0:probs = mindspore.mint.softmax(logits[:, -1] / TEMPERATURE, dim=-1)next_token = sample_top_p(probs, TOP_P)
else:next_token = mindspore.mint.argmax(logits[:, -1], dim=-1)[:, None]generated_ids[:, seq_length] = next_token[:, 0]# 自回歸生成循環
cache_position = mindspore.tensor([seq_length + 1])
for i in range(1, NUM_TOKENS_TO_GENERATE):s = time.time()next_token = decode_one_tokens(model, next_token, None, cache_position, past_key_values)generated_ids[:, cache_position] = next_token.int()cache_position += 1t = time.time()# 打印單步生成耗時print("[%d]:" % i, t - s)text = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)
print(text)

打印時間:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917870.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917870.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917870.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用phpstudy安裝php8.2后報錯:意思是找不到php_redis.dll拓展時

1.地址&#xff1a;https://pecl.php.net/package/redis/6.2.0/windows 2.下載3.解壓后復制php_redis.dll到phpstudy_pro\Extensions\php\php8.2.9nts\ext目錄 4.打開php.ini&#xff0c;加上 extension_dir “D:\software\phpstudy_pro\Extensions\php\php8.2.9nts\ext”

開源列式分布式數據庫clickhouse

這里寫自定義目錄標題開源列式OLAP數據庫clickhouseclickhouse使用 ClickHouse 的場景如何理解行式存儲和列式存儲clickhouse-go開源列式OLAP數據庫clickhouse OLAP (分析型)&#xff1a;專為快速掃描、聚合、分析海量數據設計。OLTP (事務型)&#xff1a;專為處理大量短事務&…

Java Stream API 詳解(Java 8+)

1. Stream 操作分類Stream 操作分為兩類&#xff1a;中間操作&#xff08;Intermediate Operations&#xff09;返回新的 Stream&#xff0c;可以鏈式調用&#xff08;如 filter, map, sorted, distinct&#xff09;。惰性求值&#xff1a;只有遇到終止操作時才會執行。終止操作…

「源力覺醒 創作者計劃」_文心大模型4.5系列開源模型, 從一行代碼到一個生態:聊聊開源戰略那些事兒,順便扯扯文心大模型 4.5 的使用心得

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄從一行…

算法專題(二)回文鏈表

1、源代碼class Solution {public boolean isPalindrome(ListNode head) {ListNode fasthead,slowhead; //快慢指針都在頭結點//快指針走2步&#xff0c;慢指針走一步。//雙數快指針最后是null&#xff0c;單數快指針下一位是nullwhile(fast!null && fast.next!null){f…

2025《艾諾提亞失落之歌》逆向工程解包嘗試

前言 想開發一下光明之魂&#xff0c;看能不能解包《艾諾提亞失落之歌》的模型。 之前寫了&#xff08;https://blog.csdn.net/weixin_42875245/article/details/148616547?spm1001.2014.3001.5501&#xff09; 沿用這個思路進行逆向工程解包。 文章目錄請添加圖片描述前言…

JVM 03 類加載機制

JVM 將字節碼二進制流加載到內存稱為類加載。 什么時候加載類 new 實例化對象。而對象所屬類還沒被加載。讀取/設置類的靜態非常量字段&#xff0c;常量字段在常量池。調用類的靜態方法。類初始化&#xff0c;優先初始化父類。虛擬機啟動時&#xff0c;先加載用戶指定的主類。 …

STM32H7+FreeRTOS+LwIP移植EtherCAT開源主站SOEM

代碼下載什么的就不多說了&#xff0c;直接看需要移植修改的代碼。 1、osal.c修改 /******************************************************************************* * *** **** *** *** …

VijosOJ:中文信息學競賽的二十年開源之路

VijosOJ&#xff1a;中文信息學競賽領域的老牌開源在線判題系統 在中文編程教育與信息學競賽的發展歷程中&#xff0c;在線判題系統&#xff08;OJ&#xff09;扮演了至關重要的角色。它們不僅是選手訓練的 “戰場”&#xff0c;更是知識傳遞與社區交流的樞紐。VijosOJ&#x…

QPainter::CompositionMode解析

基本概念目標(Destination)&#xff1a;已經存在的像素。源(Source)&#xff1a;要繪制的新像素。組合模式&#xff1a;決定源和目標如何混合。總結SourceOver&#xff1a;源繪制在目標之上。DestinationOver&#xff1a;目標繪制在源之上。Clear&#xff1a;二者重疊區域被清空…

對接釘釘審批過程記錄(C#版本)

釘釘開放平臺&#xff1a;API總覽 - 釘釘開放平臺 按照開放平臺操作指引&#xff0c;進入到釘釘開發者后臺&#xff1a;開發者后臺統一登錄 - 釘釘統一身份認證&#xff0c;進行應用創建。 按照開放平臺指引下載釘釘SDK&#xff08;新版&#xff09;。 在vs引入釘釘dll文件。 獲…

AFSIM入門教程03.03:更新所有依賴庫版本

系列索引&#xff1a;AFSIM入門教程索引 上一篇中更新了tiff庫版本&#xff0c;本文將更新所有使用到的依賴庫版本。 失敗了 依賴庫 首先獲取哪些庫被使用了。打開源碼目錄&#xff0c;搜索# Configure the 3rd_party&#xff0c;可以看到調用第三方庫的代碼。 官方提供的…

完美解決hive external表中csv字段內容含“,“逗號的問題

為解決hive表中csv字段內容含","逗號的問題&#xff0c;網上幾乎都是說要用org.apache.hadoop.hive.serde2.OpenCSVSerde。 使用方法為&#xff1a; 1、mysql導出時&#xff0c;加一個ENCLOSED BY ‘"’&#xff0c; 示例&#xff1a; mysql -h 10.16.0.10 -P …

【Git】修改本地和遠程的分支名稱

其原理是&#xff1a; 對于本地&#xff1a;可直接修改分支名稱&#xff1b;對于遠程&#xff1a;不可直接重命名分支&#xff0c;所以應該將修改好名稱的分支以新分支的形式推送上遠程倉庫&#xff0c;之后將新分支與遠程新分支關聯&#xff0c;之后可選擇刪除舊分支# 例子&am…

ubuntu24.04安裝selenium、chrome、chromedriver

實驗環境&#xff1a;kaggle notebook、colab notebook1、安裝chrome!wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb!sudo dpkg -i google-chrome-stable_current_amd64.deb!sudo apt-get install -f!export QT_QPA_PLATFORMoffscreen!sudo…

西門子PLC基礎指令6:讀取時鐘指令、設置時鐘指令、使能含義與注意

讀/寫指令 1. 讀取時鐘 指令 READ_RTCREAD_RTC &#xff08;RTC 全稱是 Real - Time Clock&#xff0c;即實時時鐘 &#xff09;指令的主要作用是將 CPU 內部實時時鐘&#xff08;RTC&#xff09;的當前日期和時間信息讀取出來&#xff0c;并存儲到以指定字節地址&#xff08;圖…

GeoTools 結合 OpenLayers 實現緩沖區分析

前言? 緩沖區分析是地理信息系統&#xff08;GIS&#xff09;空間分析的核心功能之一。它通過圍繞點、線或面等地理實體&#xff0c;自動生成指定距離&#xff08;或寬度&#xff09;的等距區域&#xff08;緩沖區&#xff09;。該功能為量化空間鄰近度、評估影響范圍、識別潛…

SpringBoot 接入SSE實現消息實時推送的優點,原理以及實現

SpringBoot 接入SSE實現消息實時推送的優點,原理以及實現 前言 上一篇文章 我寫的關于SpringBoot整合t-io是websocket實時通信的文章中我們可以了解到 websocket是雙向通信的,而且需要TCP連接的支持,今天在這里我要說的SSE(Server-Sent Events) 是一個單項通信的消息實時推…

創建型設計模式:對象誕生的藝術與智慧

&#x1f3ad; 創建型設計模式&#xff1a;對象誕生的藝術與智慧 &#x1f4a1; 溫馨提示&#xff1a;本文將以輕松有趣的方式帶你探索設計模式的世界&#xff0c;就像在聽一個關于"如何優雅地生孩子"的故事一樣&#xff01; &#x1f6aa; 傳送門&#xff1a;在開始…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘gensim’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘gensim’問題 摘要 在使用 PyCharm 2025 進行 Python 開發時&#xff0c;常常需要通過 pip install 安裝第三方包以豐富項目功能。但在安裝 gensim 等包時&…