欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

DeepSeek最近幾個(gè)月很火熱,很多產(chǎn)品以及企業(yè)都在接入DeepSeek,比如微信搜索接入,可以搜索公眾號(hào)信息并總結(jié),這個(gè)對(duì)于查一些資料還挺好用,因?yàn)楝F(xiàn)在很多都會(huì)在公眾號(hào)上寫一些東西,進(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 // 輸入請(qǐng)求
    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來顯示與模型的對(duì)話,其他就調(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的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論