最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android端部署DeepSeek的詳細(xì)教程

 更新時(shí)間:2025年03月25日 09:04:17   作者:技術(shù)野俠客  
DeepSeek最近幾個(gè)月很火熱,很多產(chǎn)品以及企業(yè)都在接入DeepSeek,比如微信搜索接入,可以搜索公眾號信息并總結(jié),這個(gè)對于查一些資料還挺好用,畢竟手機(jī)才是用戶用的最多的,既然談到了手機(jī),那么DeepSeek能否部署于手機(jī)之上呢,本文給大家介紹了android端部署的DeepSeek方法

DeepSeek最近幾個(gè)月很火熱,很多產(chǎn)品以及企業(yè)都在接入DeepSeek,比如微信搜索接入,可以搜索公眾號信息并總結(jié),這個(gè)對于查一些資料還挺好用,因?yàn)楝F(xiàn)在很多都會(huì)在公眾號上寫一些東西,進(jìn)行宣傳,畢竟手機(jī)才是用戶用的最多的。

既然談到了手機(jī),那么DeepSeek能否部署于手機(jī)之上呢,在不聯(lián)網(wǎng)的情況下就能使用?基于這個(gè)問題,查詢了相關(guān)資料,發(fā)現(xiàn)android端部署DeepSeek兩種方法:

第一種是使用Termux。Termux 是一款終端模擬器應(yīng)用程序,專為 Android 系統(tǒng)設(shè)計(jì),提供完整的 Linux 環(huán)境,允許用戶在 Android 設(shè)備上運(yùn)行 Linux 命令和工具,無需 root 權(quán)限。然后使用ollama相關(guān)命令下載部署模型即可。目前網(wǎng)上基本上都是這種方式,這種方式其實(shí)跟在服務(wù)端部署差不多,所以為啥不直接用服務(wù)端部署的模型呢。

第二種就是直接將模型文件下載到手機(jī)中,應(yīng)用內(nèi)直接加載模型文件并運(yùn)行,這種方式好處在于,可結(jié)合自身業(yè)務(wù)做一些基于大模型的離線本地私有化應(yīng)用,耗費(fèi)基本為0。

本文主要采用第二種方法,基于阿里MNN庫進(jìn)行部署。

MNN代碼倉庫

1 準(zhǔn)備環(huán)境

1.1 MNN轉(zhuǎn)換工具

cd MNN
mkdir build && cd build
cmake .. -DMNN_BUILD_CONVERTER=ON
make -j8

這個(gè)主要是得到MNNConvert轉(zhuǎn)換工具,可用來轉(zhuǎn)換onnx格式為mnn格式

1.2 大模型轉(zhuǎn)換工具

安裝大模型轉(zhuǎn)換工具需要的一些依賴,可用conda來進(jìn)行環(huán)境管理

cd path/MNN/transformers/llm/export
pip install -r requirements.txt

如果只是想試試大模型android端部署,把這些依賴下載下來,然后使用如下方式一轉(zhuǎn)換模型就行了

1.3 模型下載

git lfs install
git clone https://www.modelscope.cn/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B.

1.4 模型轉(zhuǎn)換

方式一:直接使用llmexport.py直接轉(zhuǎn)換得到mnn格式的模型文件

python llmexport.py --path path/model/DeepSeek-R1-Distill-Qwen-1.5B --export mnn

方式二:可先轉(zhuǎn)換為onnx,然后再使用MNNConvert轉(zhuǎn)換為mnn格式模型

python llmexport.py --path path/model/DeepSeek-R1-Distill-Qwen-1.5B --export onnx ./MNNConvert -f ONNX --modelFile llm.onnx --MNNModel llm.mnn --bizCode biz

兩種方式都嘗試過,轉(zhuǎn)換出來的模型都沒啥問題,方式二主要可以進(jìn)行其他bits數(shù)的量化

成功:

產(chǎn)物解釋:

1.5 編譯android依賴庫

cd project/android
mkdir build_64 && cd build_64
../build_64.sh "-DMNN_LOW_MEMORY=true -DMNN_CPU_WEIGHT_DEQUANT_GEMM=true -DMNN_BUILD_LLM=true -DMNN_SUPPORT_TRANSFORMER_FUSE=true -DMNN_ARM82=true -DMNN_OPENCL=true -DMNN_USE_LOGCAT=true"
mkdir build_32 && cd build_32
../build_32.sh "-DMNN_LOW_MEMORY=true -DMNN_CPU_WEIGHT_DEQUANT_GEMM=true -DMNN_BUILD_LLM=true -DMNN_SUPPORT_TRANSFORMER_FUSE=true -DMNN_ARM82=true -DMNN_OPENCL=true -DMNN_USE_LOGCAT=true"

這個(gè)主要是用于編譯android需要用的mnn庫,編譯完成后將*.so文件將其放在android工程中

提示:如果需要調(diào)試mnn庫,需要將build_64/32.sh文件中的如下參數(shù)設(shè)置為true

2 android工程

主要介紹一下其中一些關(guān)鍵的點(diǎn):CMakeList文件的編寫、JNI文件的編寫,以及簡要說一下android native的實(shí)現(xiàn)

2.1 頭文件導(dǎo)入

將MNN庫中的頭文件(要包含llm.hpp頭文件),以及1.5編譯的android依賴庫放入android工程中,目錄如下:

2.2 CMakeList

cmake_minimum_required(VERSION 3.10.2)

project("my_deep_seek")

aux_source_directory(./ SRC_LIST)

add_library(my_deep_seek SHARED ${SRC_LIST})

find_library(log-lib log)
find_library(android-lib android)

include_directories(${CMAKE_SOURCE_DIR}/mnn/include)
include_directories(${CMAKE_SOURCE_DIR}/mnn/include/expr/)
add_library(libMNN STATIC IMPORTED)
add_library(libMNN_CL STATIC IMPORTED)
add_library(libMNN_Express STATIC IMPORTED)
add_library(libllm STATIC IMPORTED)
set_target_properties(
        libMNN PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/mnn/${CMAKE_ANDROID_ARCH_ABI}/libMNN.so
)
set_target_properties(
        libMNN_CL PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/mnn/${CMAKE_ANDROID_ARCH_ABI}/libMNN_CL.so
)
set_target_properties(
        libMNN_Express PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/mnn/${CMAKE_ANDROID_ARCH_ABI}/libMNN_Express.so
)
set_target_properties(
        libllm PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/mnn/${CMAKE_ANDROID_ARCH_ABI}/libllm.so
)

message("===>>>> abi is : ${CMAKE_ANDROID_ARCH_ABI} <<<<===")

target_link_libraries(
        my_deep_seek

        ${log-lib}
        ${android-lib}
        libMNN
        libMNN_CL
        libMNN_Express
        libllm
)

2.3 JNI

class Chat : Serializable {
    companion object {
        init {
            System.loadLibrary("my_deep_seek")
        }
    }

    external fun Init(modelDir: String): Boolean // 加載模型
    external fun Submit(input: String): String // 輸入請求
    external fun Respose(): ByteArray // 模型輸出
    external fun Done()
    external fun Reset()
}
#include <android/asset_manager_jni.h>
#include <android/bitmap.h>
#include <android/log.h>

#include <jni.h>
#include <string>
#include <vector>
#include <sstream>
#include <thread>

#include "MNN/llm.hpp"

#ifndef LOG_TAG
#define LOG_TAG "MyDeepSeek"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG ,__VA_ARGS__) // 定義LOGD類型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG ,__VA_ARGS__) // 定義LOGI類型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG ,__VA_ARGS__) // 定義LOGW類型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG ,__VA_ARGS__) // 定義LOGE類型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG ,__VA_ARGS__) // 定義LOGF類型
#endif

static std::unique_ptr<MNN::Transformer::Llm> llm(nullptr);
static std::stringstream response_buffer;

extern "C" {

// 模型加載
JNIEXPORT jboolean JNICALL
Java_com_example_mydeepseek_Chat_Init(JNIEnv *env, jobject thiz, jstring modelDir) {
    const char* model_dir = env->GetStringUTFChars(modelDir, 0);
    if (!llm.get()) {
        llm.reset(MNN::Transformer::Llm::createLLM(model_dir));
        try {
            llm->load();
        } catch (const std::exception& e) {
            LOGI("=== 異常:%s ====", e.what());
            return JNI_FALSE;
        }
    }
    return JNI_TRUE;
}

// 將問題輸入模型
JNIEXPORT jstring JNICALL
Java_com_example_mydeepseek_Chat_Submit(JNIEnv *env, jobject thiz, jstring inputStr) {
    if (!llm.get()) {
        return env->NewStringUTF("Failed, Chat is not ready!");
    }
    const char* input_str = env->GetStringUTFChars(inputStr, 0);
    auto chat = [&](std::string str) {
        llm->response(str, &response_buffer, "<eop>");
    };
    std::thread chat_thread(chat, input_str); //子線程運(yùn)行
    chat_thread.detach();
    jstring result = env->NewStringUTF("Submit success!");
    return result;
}

// 取出模型輸出
JNIEXPORT jbyteArray JNICALL
Java_com_example_mydeepseek_Chat_Respose(JNIEnv *env, jobject thiz) {
    auto len = response_buffer.str().size();
    jbyteArray res = env->NewByteArray(len);
    env->SetByteArrayRegion(res, 0, len, (const jbyte*)response_buffer.str().c_str());
    return res;
}

JNIEXPORT void JNICALL
Java_com_example_mydeepseek_Chat_Done(JNIEnv *env, jobject thiz) {
    response_buffer.str("");
}

JNIEXPORT void JNICALL
Java_com_example_mydeepseek_Chat_Reset(JNIEnv *env, jobject thiz) {
    llm->reset();
}

} // extern "C"

2.4 android native

app實(shí)現(xiàn)方面比較簡單,使用recycleview來顯示與模型的對話,其他就調(diào)用jni接口即可

(1)加載模型

將1.4節(jié)模型轉(zhuǎn)換得到的那些文件將其放到手機(jī)的/data/local/tmp/DeepSeek-R1-Distill-Qwen-1.5B目錄下,然后mModelDir就為/data/local/tmp/DeepSeek-R1-Distill-Qwen-1.5B/llm.mnn

Thread {
    mChat = Chat()
    if (mChat?.Init(mModelDir) == true) {
        runOnUiThread {
            mIntent?.putExtra("chat", mChat)
            startActivityForResult(mIntent, 100)
        }
    } else {
        Toast.makeText(this,"加載模型失敗", Toast.LENGTH_SHORT).show()
    }
}.start()

(2)向模型輸入

mChat?.Submit(input)

(3)得到模型輸出

Thread {
    mChat?.Submit(input) // 輸入
    var lastResponse = ""
    while (!lastResponse.contains("<eop>")) { // 模型輸出結(jié)束標(biāo)志"<eop>"
        try {
            Thread.sleep(50) // 等模型輸出一點(diǎn)信息
            val response: String = String(mChat?.Respose() ?: ByteArray(0))
            if (response != lastResponse) {
                lastResponse = response
                lifecycleScope.launch {
                    updateBotResponse(
                        response.replaceFirst(
                            "<eop>".toRegex(),
                            ""
                        )
                    )
                }
            }
        } catch (e: InterruptedException) {
            Thread.currentThread().interrupt()
        }
    }
    mChat?.Done()
}

3 總結(jié)

1.5B模型,運(yùn)行內(nèi)存最高1.5G,推理時(shí)1G,占用內(nèi)存還挺多,且模型性能相比云端模型還是差很多。但需向前看,最近阿里的QwQ-32B模型不是達(dá)到了DeepSeek 671B模型的性能了嗎,甚至某些方面還超越DeepSeek,發(fā)展還是很快的。說不定后面不到1B參數(shù)的模型,性能可比肩671B模型,狠狠期待一下。

以上就是Android端部署DeepSeek的詳細(xì)教程的詳細(xì)內(nèi)容,更多關(guān)于Android端部署DeepSeek的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android編程實(shí)現(xiàn)攔截短信并屏蔽系統(tǒng)Notification的方法

    Android編程實(shí)現(xiàn)攔截短信并屏蔽系統(tǒng)Notification的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)攔截短信并屏蔽系統(tǒng)Notification的方法,較為詳細(xì)的分析了Android短信與Notification的原理及對應(yīng)的設(shè)置取消技巧,需要的朋友可以參考下
    2015-12-12
  • Android繪圖之Paint的使用方法詳解

    Android繪圖之Paint的使用方法詳解

    這篇文章主要給大家介紹了關(guān)于Android繪圖之Paint使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),并給大家介紹了DrawText 基線確定的方法,需要的朋友可以參考借鑒,下面隨著小編來一些學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • Android Jetpack組件庫LiveData源碼深入探究

    Android Jetpack組件庫LiveData源碼深入探究

    LiveData是Jetpack組件的一部分,更多的時(shí)候是搭配ViewModel來使用,相對于Observable,LiveData的最大優(yōu)勢是其具有生命感知的,換句話說,LiveData可以保證只有在組件( Activity、Fragment、Service)處于活動(dòng)生命周期狀態(tài)的時(shí)候才會(huì)更新數(shù)據(jù)
    2022-09-09
  • android中關(guān)于call撥號功能的實(shí)現(xiàn)方法

    android中關(guān)于call撥號功能的實(shí)現(xiàn)方法

    這篇文章主要介紹了android中關(guān)于call撥號功能實(shí)現(xiàn)的記錄,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-05-05
  • android手機(jī)獲取唯一標(biāo)識的方法

    android手機(jī)獲取唯一標(biāo)識的方法

    這篇文章主要 為大家詳細(xì)介紹了android手機(jī)獲取唯一標(biāo)識的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Android 手勢 正則匹配圖片實(shí)例代碼

    Android 手勢 正則匹配圖片實(shí)例代碼

    這篇文章主要介紹了Android 手勢 正則匹配圖片實(shí)例代碼,需要的朋友可以參考下
    2017-07-07
  • Android學(xué)習(xí)系列一用按鈕實(shí)現(xiàn)顯示時(shí)間

    Android學(xué)習(xí)系列一用按鈕實(shí)現(xiàn)顯示時(shí)間

    這篇文章主要介紹了Android學(xué)習(xí)系列一用按鈕實(shí)現(xiàn)顯示時(shí)間的相關(guān)資料,需要的朋友可以參考下
    2016-05-05
  • Android相機(jī)、圖冊demo

    Android相機(jī)、圖冊demo

    這篇文章主要為大家詳細(xì)介紹了Android相機(jī)、圖冊的基本常見使用方法,幾乎涵蓋了Android相機(jī)、圖冊操作方法,感興趣的小伙伴們可以參考一下
    2016-04-04
  • Android控件動(dòng)態(tài)用法實(shí)例分析

    Android控件動(dòng)態(tài)用法實(shí)例分析

    這篇文章主要介紹了Android控件動(dòng)態(tài)用法,以實(shí)例形式較為詳細(xì)的分析了Android控件動(dòng)態(tài)的具體編程實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • Android NavigationBar問題處理的方法

    Android NavigationBar問題處理的方法

    本篇文章主要介紹了Android NavigationBar問題處理的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論

涞源县| 长泰县| 宜阳县| 华池县| 登封市| 定远县| 宜城市| 台州市| 宁国市| 东阿县| 长岭县| 博湖县| 南郑县| 子长县| 连山| 喀喇| 甘德县| 镇安县| 通江县| 湛江市| 柏乡县| 那坡县| 稷山县| 潮州市| 石景山区| 乡城县| 温州市| 肃南| 贡觉县| 库车县| 平顶山市| 长治市| 鄂州市| 塘沽区| 永定县| 千阳县| 大丰市| 胶南市| 仁布县| 阿鲁科尔沁旗| 故城县|