# qwen3-asr-java **Repository Path**: wuyuan/qwen3-asr-java ## Basic Information - **Project Name**: qwen3-asr-java - **Description**: jllama 运行 qwen3 asr(纯java) - **Primary Language**: Unknown - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-21 - **Last Updated**: 2026-09-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Qwen3-ASR Java Server(方案 A) 基于 `net.ladenthin:llama:5.1.0`(捆绑 llama.cpp **b11069**)内嵌的完整 llama-server, 在 Java 进程内直接提供 **Qwen3-ASR** 语音转写服务,Python / 任意 HTTP 客户端通过 OpenAI 兼容接口调用。无需 ONNX、无需自己拼 embedding —— llama.cpp 从 b8769 起已原生支持 Qwen3-ASR 音频输入(libmtmd,decoder + mmproj 两个 GGUF)。 ``` 音频文件 ──base64──▶ POST /v1/chat/completions (content: input_audio) │ net.ladenthin:llama 5.1.0 内嵌 llama-server (llama.cpp b11069) │ Qwen3-ASR GGUF (model.gguf + mmproj.gguf) + GPU 加速 ▼ choices[0].message.content ← 转写文本 ``` ## 目录结构 ``` qwen3-asr-java/ ├── pom.xml # Maven 工程(含 GPU 分类器 profile) ├── lib/ # CPU 运行时 jar(本仓库免 Maven 直接跑) │ ├── llama-5.1.0.jar # llama.cpp Java 绑定(CPU,全平台;含 jackson 等运行时依赖) │ └── llama-5.1.0.jar.orig # 原版未改动 CPU jar(备份) ├── lib-gpu/ # GPU 分类器 jar(用 GPU 时按 README 换入 lib/) │ └── llama-5.1.0-vulkan-linux-x86-64.jar ├── classes/ # javac 编译输出 ├── src/main/java/com/qwen3asr/Qwen3AsrServer.java ├── scripts/ │ ├── download_models.py # 下载官方 GGUF 模型 │ ├── test_transcribe.py # 转写测试(纯标准库) │ └── generate_test_audio.py # 生成冒烟测试音频(纯音调,非语音) ├── models/ # 模型目录(下载脚本放入) └── test-audio/ # 测试音频(tone.wav + 真实英文语音样本 sample_speech_16k.wav) ``` ## 快速开始 ### 1. 下载模型(二选一) ```bash python3 scripts/download_models.py # 默认 1.7B Q8_0(约 2.4GB) python3 scripts/download_models.py --model 0.6b # 0.6B(约 1GB,先跑通链路用) ``` 模型来自官方仓库 `ggml-org/Qwen3-ASR-{0.6B|1.7B}-GGUF`,Q8_0 量化。 ### 2. 启动服务 本仓库已把运行时 jar 放在 `lib/`,装好 JDK(11+)即可直接跑,不需要 Maven: ```bash # CPU 模式 java -cp "lib/*:classes" com.qwen3asr.Qwen3AsrServer \ --model models/Qwen3-ASR-0.6B-Q8_0.gguf \ --mmproj models/mmproj-Qwen3-ASR-0.6B-Q8_0.gguf \ --port 8080 -ngl 0 ``` 看到 `READY -> http://127.0.0.1:8080/v1/chat/completions` 即就绪。 参数说明: | 参数 | 默认 | 说明 | |---|---|---| | `--model` | 必填 | Qwen3-ASR 主模型 GGUF | | `--mmproj` | 必填 | 音频投影 GGUF | | `--port` | 8080 | 监听端口 | | `--host` | 127.0.0.1 | 监听地址(外部访问改 `0.0.0.0`) | | `-ngl` | 99 | 卸载到 GPU 的层数(99=全量;CPU 用 0) | | `-c` | 8192 | 上下文大小(长音频需要大上下文) | | `--timeout` | 300 | 启动就绪等待秒数 | ### 3. 转写测试 ```bash python3 scripts/test_transcribe.py --file 你的录音.wav --url http://127.0.0.1:8080 ``` 支持 wav / mp3 / flac(服务器端自动解码)。结果打印在 `识别结果:` 后面。 ## GPU 加速(本机有 GPU 时) 绑定预编译了各 GPU 后端,通过 Maven classifier 引入(与默认 CPU 包**二选一**): | 显卡 | 后端 | Maven profile | classifier | |---|---|---|---| | NVIDIA / AMD / Intel(推荐) | Vulkan | `-Pgpu-vulkan-linux` / `-Pgpu-vulkan-win` | `vulkan-linux-x86-64` / `vulkan-windows-x86-64` | | NVIDIA(需 CUDA 驱动) | CUDA 13 | `-Pgpu-cuda-linux` / `-Pgpu-cuda-win` | `cuda13-linux-x86-64` / `cuda13-windows-x86-64` | ```bash # 例如 Windows + Vulkan: mvn -Pgpu-vulkan-win -DskipTests package # 启动(-ngl 99 全量卸载到 GPU) java -jar target/qwen3-asr-java-1.0.0-jar-with-dependencies.jar \ --model models/Qwen3-ASR-1.7B-Q8_0.gguf \ --mmproj models/mmproj-Qwen3-ASR-1.7B-Q8_0.gguf \ --port 8080 -ngl 99 ``` 启动日志中出现 `llm_load_tensors: offloaded N/N layers to GPU` 即 GPU 生效。 > 无 Maven 环境也可手工替换:把 `lib-gpu/` 里的分类器 jar 放入 `lib/`,并移走/删除 > `lib/llama-5.1.0.jar`(分类器 jar 已含全部 Java 类 + GPU native;两个 jar 同时存在会导致 > native 从错误的后端加载)。Windows 的 Vulkan/CUDA 分类器需用对应 profile 从 Maven 下载。 ## 常见问题 **Q: Linux 启动报 `GLIBC_2.38 not found`?** 预编译 native 基于较新的 glibc(≥2.38,约 Ubuntu 24.04+)。老发行版(如 Ubuntu 22.04 glibc 2.35)请: 升级系统,或改用 Windows 版(无 glibc 依赖),或按下文「从源码编译 native」自建。 **Q: 从源码编译 native(老 glibc / 自建 GPU 后端)?** 本仓库已在 Ubuntu 22.04(glibc 2.35)上从源码编译成功并完成端到端验证,步骤如下: ```bash git clone https://github.com/bernardladenthin/java-llama.cpp cd java-llama.cpp cmake -S llama -B build-cpu -G Ninja -DCMAKE_BUILD_TYPE=Release \ -DOS_NAME=Linux -DOS_ARCH=x86_64 # 跳过依赖 lombok/jspecify 的 Java OSInfo 探测 cmake --build build-cpu --target jllama # 产物:llama/src/main/resources/net/ladenthin/llama/Linux/x86_64/libjllama.so # 用 jar 工具替换进 llama-5.1.0.jar 同名条目即可(本仓库 lib/llama-5.1.0.jar 已替换) ``` 注意:GPU 分类器 jar 是官方预编译的,直接使用无需编译;只有 Linux 老 glibc 上跑 CPU 版 才需要走这条路。 **Q: 服务起不来 / 端口占用?** 换 `--port`。就绪判定是轮询 `GET /health` 返回 `{"status":"ok"}`,失败会打印原因。 **Q: 转写结果为空或乱码?** - 纯音调/静音不是语音,识别为空属正常(可用 `generate_test_audio.py` 只做链路冒烟); - 检查 GPU:`-ngl 99` 但驱动不支持时,改 `-ngl 0` 对比; - 长音频加大 `-c`(如 16384)。 **Q: 模型文件校验?** ```bash sha256sum models/*.gguf # Qwen3-ASR-0.6B-Q8_0.gguf = bca259818b50ca7c4c05e9bdb35a5dc04fa039653a6d6f3f0f331f96f6aa1971 # mmproj-Qwen3-ASR-0.6B-Q8_0.gguf = 41a342b5e4c514e968cb756de6cd1b7be39eff43c44c57a2ef5fc6522e36603d ``` ## 已验证项(本仓库实测) - ✅ Java 源码编译通过(JDK 17,目标 Java 11) - ✅ 模型下载完整,sha256 与 HuggingFace 官方一致 - ✅ **端到端真实转写**(0.6B Q8_0,CPU,端口 18082): - `NativeServer` 加载 `Qwen3-ASR-0.6B-Q8_0.gguf` + `mmproj` 成功,`listening on http://127.0.0.1:18082` - `GET /health` 就绪轮询 → `READY` - 真实英文语音 `test-audio/sample_speech_16k.wav` 转写输出正确文本 (`language EnglishThe birch canoe slid on the smooth planks...`) - 纯音调 `tone.wav` 返回空 ``(无语音时行为正常) - ⚠️ GPU 加速(`-ngl 99` + Vulkan/CUDA 分类器)需在你的机器上验证:本仓库开发环境无 GPU, 已按 README 方式准备好 classifier jar 与启动命令;日志中出现 `offloaded N/N layers to GPU` 即生效 ## 参考 - 绑定:https://github.com/bernardladenthin/java-llama.cpp (net.ladenthin:llama:5.1.0 = llama.cpp b11069) - llama.cpp Qwen3-ASR 支持:b8769 合并,官方 GGUF:https://huggingface.co/ggml-org/Qwen3-ASR-1.7B-GGUF