使用Android Studio部署手机端离线RAG,手把手教你手机也能实现RAG+Deepseek

张开发
2026/5/17 18:34:26 15 分钟阅读
使用Android Studio部署手机端离线RAG,手把手教你手机也能实现RAG+Deepseek
1.准备可以用于手机端侧部署的deepseek模型文件一般是gguf格式或者tflite格式的2.准备嵌入模型和分词模型一般是gguf格式或者tflite格式的3.编写模型加载和模型推理的代码用Java或者kotlin语言简单写个聊天框即可重点在于写怎么跟模型交互的代码4.编写文本嵌入的代码怎么进行文本分块怎么进行嵌入模型的加载怎么进行存储5.用Android Studio 运行编译成可以在手段端侧运行的apk。6.运行结果如图所示需要全套代码和模型文件以及怎么编译运行的看评论区。手把手教学怎么实现以下是基于你的需求的详细代码和步骤包括模型准备、加载、推理、文本嵌入、分块、存储以及如何在Android Studio中编译运行的完整指南。本文 Android 端侧离线 ASR 全套代码、模型包、部署文档已同步至我的公众号 【科技低语】关注回复 【端侧RAG】 一键领取持续更新端侧 AI 落地实战。一、准备工作1.1 模型准备你需要准备以下模型文件DeepSeek 模型用于生成对话的模型可以是gguf或tflite格式。嵌入模型用于生成文本嵌入的模型可以是gguf或tflite格式。分词模型用于对输入文本进行分词的模型通常是一个词典文件或gguf格式。1.2 环境准备Android Studio确保已安装最新版本。TensorFlow Lite如果使用tflite格式模型需要添加 TensorFlow Lite 依赖。Llama.cpp 或 DeepSeek 库如果使用gguf格式模型需要通过 JNI 调用 C 代码。二、项目设置2.1 创建 Android 项目打开 Android Studio创建一个新的安卓项目。选择适合的模板如 Empty Activity并配置项目名称、包名等基本信息。2.2 添加依赖在项目的build.gradle文件中添加以下依赖gradle复制dependencies { implementation org.tensorflow:tensorflow-lite:2.9.0 implementation org.tensorflow:tensorflow-lite-support:2.9.0 }三、模型加载和推理3.1 加载模型根据模型格式选择不同的加载方式3.1.1 使用tflite格式模型java复制import org.tensorflow.lite.Interpreter; import java.io.FileInputStream; import java.io.IOException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class ModelLoader { private Interpreter tflite; public ModelLoader(Context context, String modelPath) throws IOException { tflite new Interpreter(loadModelFile(context, modelPath)); } private MappedByteBuffer loadModelFile(Context context, String modelPath) throws IOException { AssetFileDescriptor fileDescriptor context.getAssets().openFd(modelPath); FileInputStream inputStream new FileInputStream(fileDescriptor.getFileDescriptor()); FileChannel fileChannel inputStream.getChannel(); long startOffset fileDescriptor.getStartOffset(); long declaredLength fileDescriptor.getDeclaredLength(); return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength); } public Interpreter getInterpreter() { return tflite; } }3.1.2 使用gguf格式模型对于gguf格式模型需要通过 JNI 调用 C 代码。以下是简单的 JNI 示例java复制public class GGUFModelLoader { static { System.loadLibrary(gguf); } public native void loadModel(Context context, String modelPath); }3.2 模型推理根据模型格式选择不同的推理方式3.2.1 使用tflite格式模型java复制public class DeepSeekChat { private Interpreter tflite; public DeepSeekChat(Context context, String modelPath) throws IOException { ModelLoader modelLoader new ModelLoader(context, modelPath); tflite modelLoader.getInterpreter(); } public String chat(String input) { // 将输入文本转换为模型所需的格式 float[] inputTensor preprocessInput(input); // 创建输出张量 float[][] outputTensor new float[1][10]; // 假设输出维度为 1x10 // 运行推理 tflite.run(inputTensor, outputTensor); // 将输出张量转换为文本 return postprocessOutput(outputTensor); } private float[] preprocessInput(String input) { // 根据模型需求对输入进行预处理 // 示例将输入文本转换为浮点数组 return new float[10]; // 示例数组 } private String postprocessOutput(float[][] output) { // 根据模型输出进行后处理生成可读的文本 return DeepSeek 的回复; // 示例回复 } }3.2.2 使用gguf格式模型java复制public class DeepSeekChat { static { System.loadLibrary(gguf); } public native String chat(String input); }四、文本嵌入和分块4.1 文本分块java复制public class TextChunker { public static ListString chunkText(String text, int chunkSize) { ListString chunks new ArrayList(); int textLength text.length(); for (int i 0; i textLength; i chunkSize) { int end Math.min(i chunkSize, textLength); chunks.add(text.substring(i, end)); } return chunks; } }4.2 嵌入模型加载和推理java复制public class EmbeddingModel { private Interpreter tflite; public EmbeddingModel(Context context, String modelPath) throws IOException { ModelLoader modelLoader new ModelLoader(context, modelPath); tflite modelLoader.getInterpreter(); } public float[] getEmbedding(String text) { // 将文本转换为模型输入格式 float[] inputTensor preprocessInput(text); // 创建输出张量 float[] outputTensor new float[128]; // 假设嵌入维度为 128 // 运行推理 tflite.run(inputTensor, outputTensor); return outputTensor; } private float[] preprocessInput(String text) { // 根据模型需求对输入进行预处理 // 示例将输入文本转换为浮点数组 return new float[10]; // 示例数组 } }4.3 嵌入存储使用 SQLite 数据库存储嵌入向量java复制public class EmbeddingDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME embeddings.db; private static final int DATABASE_VERSION 1; public EmbeddingDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } Override public void onCreate(SQLiteDatabase db) { String CREATE_TABLE CREATE TABLE embeddings (id INTEGER PRIMARY KEY, text TEXT, embedding BLOB); db.execSQL(CREATE_TABLE); } Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL(DROP TABLE IF EXISTS embeddings); onCreate(db); } public void insertEmbedding(String text, float[] embedding) { SQLiteDatabase db this.getWritableDatabase(); ContentValues values new ContentValues(); values.put(text, text); values.put(embedding, serializeEmbedding(embedding)); db.insert(embeddings, null, values); db.close(); } private byte[] serializeEmbedding(float[] embedding) { ByteArrayOutputStream bos new ByteArrayOutputStream(); DataOutputStream dos new DataOutputStream(bos); try { for (float value : embedding) { dos.writeFloat(value); } return bos.toByteArray(); } catch (IOException e) { e.printStackTrace(); return null; } } }五、聊天界面实现5.1 创建对话界面在activity_main.xml中创建一个简单的对话界面xml复制LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:layout_widthmatch_parent android:layout_heightmatch_parent android:orientationvertical ListView android:idid/conversation_list android:layout_widthmatch_parent android:layout_height0dp android:layout_weight1 / EditText android:idid/input_text android:layout_widthmatch_parent android:layout_heightwrap_content android:hint输入你的问题... / Button android:idid/send_button android:layout_widthmatch_parent android:layout_heightwrap_content android:text发送 / /LinearLayout5.2 实现对话逻辑在MainActivity.java中实现对话逻辑java复制public class MainActivity extends AppCompatActivity { private ListView conversationList; private EditText inputText; private Button sendButton; private ArrayAdapterString adapter; private DeepSeekChat deepSeekChat; private EmbeddingModel embeddingModel; private EmbeddingDatabaseHelper dbHelper; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化 UI 组件 conversationList findViewById(R.id.conversation_list); inputText findViewById(R.id.input_text); sendButton findViewById(R.id.send_button); // 初始化适配器 adapter new ArrayAdapter(this, android.R.layout.simple_list_item_1); conversationList.setAdapter(adapter); // 初始化模型 try { // 加载 DeepSeek 模型 deepSeekChat new DeepSeekChat(this, model.tflite); // 加载嵌入模型 embeddingModel new EmbeddingModel(this, embedding_model.tflite); // 初始化数据库 dbHelper new EmbeddingDatabaseHelper(this); } catch (IOException e) { e.printStackTrace(); } // 设置发送按钮的点击事件 sendButton.setOnClickListener(v - { String userInput inputText.getText().toString(); if (!userInput.isEmpty()) { // 添加用户输入到对话列表 adapter.add(User: userInput); // 获取 DeepSeek 的回复 String response deepSeekChat.chat(userInput); // 添加回复到对话列表 adapter.add(DeepSeek: response); // 对输入文本进行分块 ListString chunks TextChunker.chunkText(userInput, 100); // 对每个分块进行嵌入并存储 for (String chunk : chunks) { float[] embedding embeddingModel.getEmbedding(chunk); dbHelper.insertEmbedding(chunk, embedding); } // 清空输入框 inputText.setText(); } }); } }六、编译和运行6.1 编译项目打开 Android Studio选择 Build - Rebuild Project。确保没有错误后选择 Build - Generate Signed Bundle / APK。按照提示生成签名的 APK 文件。6.2 运行应用连接安卓设备到电脑确保设备已启用 USB 调试。在 Android Studio 中选择 Run - Run app。应用将安装并运行在连接的设备上。七、模型文件和代码下载由于模型文件较大无法直接提供。你可以在以下资源中找到适合的模型文件DeepSeek 模型Llama.cpp将模型文件放入项目的assets文件夹中并确保路径正确。八、运行结果运行应用后你将看到一个简单的聊天界面可以输入问题并获得 DeepSeek 的回复。输入的文本将被分块、嵌入并存储在 SQLite 数据库中。

更多文章