# LLM 推理服务 为 [minor Agent](../README.md) 提供本地化推理后端,包含 **6 个独立服务**,均跑在 GPU 服务器上,通过 OpenAI 兼容 / 自定义 HTTP API 暴露。可整体部署,也可按需启用。 ## 服务总览 | 服务 | 端口 | 模型 | 启动脚本 | Python 服务端 | 关键端点 | |------|:----:|------|----------|---------------|----------| | **LLM** | 8900 | Qwen3.6-35B-A3B-FP8 | `start_llm.sh` | vLLM 内置 | `/v1/chat/completions` | | **ASR** | 8901 | Qwen3-ASR-1.7B | `start_asr.sh` | vLLM 内置 | `/v1/chat/completions` | | **TTS** | 8902 | VoxCPM 1.5 / 2 | `start_streaming_tts.sh` | `streaming_tts_server.py` | `/stream_tts` | | **RAG** | 8903 | Embedding-0.6B + Reranker-4B | `start_rag_server.sh` | `rag_server.py` | `/embed` `/rerank` | | **Image Gen** | 8904 | Z-Image-Turbo | `start_image_gen.sh` | `image_gen_server.py` | `/generate` | > 所有脚本 / Python 文件均通过 `os.path.dirname(__file__)` 与 `${SCRIPT_DIR}` 动态定位模型路径,**目录整体迁移无需改代码**。 --- ## 一、部署流程 ### 1. 上传到服务器 ```bash scp -P -r Agent/llm_server/* @:~/llm_server/ ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -p @ ``` ### 2. 服务器环境 ```bash cd ~/llm_server chmod +x *.sh # HuggingFace 镜像加速(国内必需) export HF_ENDPOINT=https://hf-mirror.com export HF_HUB_ENABLE_XET=0 echo 'export HF_ENDPOINT=https://hf-mirror.com' >> ~/.bashrc echo 'export HF_HUB_ENABLE_XET=0' >> ~/.bashrc python3 -m venv myenv && source myenv/bin/activate # 一次性安装全部依赖 pip install vllm modelscope transformers fastapi uvicorn torch numpy torchaudio soundfile \ bitsandbytes huggingface_hub voxcpm diffusers sudo apt update && sudo apt install -y ffmpeg libavcodec-dev libavformat-dev libavutil-dev \ libavdevice-dev libavfilter-dev libswscale-dev libswresample-dev ``` ### 3. 下载模型 所有模型统一存放 `~/llm_server/models/`: | 模型 | 命令 | |------|------| | Qwen3.6-35B-A3B-FP8 (LLM) | `modelscope download --model Qwen/Qwen3.6-35B-A3B-FP8 --local_dir ./models/Qwen/Qwen3___6-35B-A3B-FP8` | | Qwen3-ASR-1.7B | `modelscope download --model Qwen/Qwen3-ASR-1.7B --local_dir ./models/Qwen/Qwen3-ASR-1.7B` | | Qwen3-Embedding-0.6B | `modelscope download --model Qwen/Qwen3-Embedding-0.6B --local_dir ./models/Qwen/Qwen3-Embedding-0___6B` | | Qwen3-Reranker-4B | `modelscope download --model Qwen/Qwen3-Reranker-4B --local_dir ./models/Qwen/Qwen3-Reranker-4B` | | VoxCPM 1.5 (推荐) | `modelscope download --model OpenBMB/VoxCPM1.5 --local_dir ./models/VoxCPM1__5` | | VoxCPM 2 (音质更佳) | `modelscope download --model OpenBMB/VoxCPM2 --local_dir ./models/VoxCPM2` | | Z-Image-Turbo | `modelscope download --model Tongyi-MAI/Z-Image-Turbo --local_dir ./models/Tongyi-MAI/Z-Image-Turbo` | 完成后目录结构: ``` ~/llm_server/models/ ├── Qwen/ │ ├── Qwen3___6-35B-A3B-FP8/ # LLM │ ├── Qwen3-ASR-1.7B/ # ASR │ ├── Qwen3-Embedding-0___6B/ # Embedding │ └── Qwen3-Reranker-4B/ # Reranker ├── VoxCPM1__5/ # TTS └── Tongyi-MAI/Z-Image-Turbo/ # Image Gen ``` --- ## 二、启动与测试 每个服务独立启动,互不依赖。所有 `start_*.sh` 支持环境变量覆盖: | 环境变量 | 作用 | 适用脚本 | |----------|------|----------| | `HOST_PORT` | 服务端口 | 全部 | | `LOCAL_MODEL_DIR` / `MODEL_PATH` / `VOXCPM_MODEL_PATH` | 模型目录 | 全部 | | `CUDA_VISIBLE_DEVICES` | GPU 设备号 | 全部 | | `SPECIFIC_GPU` | 单 GPU 指定(写 `CUDA_VISIBLE_DEVICES`) | image_gen / tts | | `SERVER_API_KEY` | API Key 鉴权(空=不校验,任意值放行) | 全部 | | `SERVER_MODELNAME` | 服务模型名(请求 body.model 须匹配;空=不校验) | 全部 | > **鉴权与模型名校验**:`SERVER_API_KEY` 为空时服务不校验 API Key(任意值放行); > `SERVER_MODELNAME` 为空时服务不校验请求中的 `model` 字段。 > 部署时如需启用,示例: > ```bash > SERVER_API_KEY=sk-xxx SERVER_MODELNAME=Qwen3-ASR-1.7B bash start_asr.sh > ``` ### LLM · 8900 ```bash bash start_llm.sh # 启用鉴权与自定义模型名 # SERVER_API_KEY=sk-xxx SERVER_MODELNAME=Qwen/Qwen3.6-35B-A3B-FP8 bash start_llm.sh # 测试 python3 test_llm.py --url http://127.0.0.1:8900 # 非流式 python3 test_llm.py --url http://127.0.0.1:8900 --stream # 流式 ``` > vLLM 加载 Qwen3.6-35B-A3B-FP8,OpenAI 兼容 API,使用 `chat_template.jinja` 格式化对话。 > `--served-model-name` 由 `SERVER_MODELNAME` 控制(默认 `Qwen/Qwen3.6-35B-A3B-FP8`); > `SERVER_API_KEY` 非空时传给 vLLM `--api-key`,请求需携带 `Authorization: Bearer `。 ### ASR · 8901 ```bash bash start_asr.sh # 启用鉴权与自定义模型名 # SERVER_API_KEY=sk-xxx SERVER_MODELNAME=Qwen3-ASR-1.7B bash start_asr.sh # 测试 python3 test_asr.py --audio /path/to/audio.wav --url http://127.0.0.1:8901/v1/chat/completions ``` > vLLM 加载 Qwen3-ASR-1.7B,`--served-model-name` 由 `SERVER_MODELNAME` 控制(默认 `Qwen3-ASR-1.7B`)。 ### TTS · 8902(流式) ```bash bash start_streaming_tts.sh # 启用鉴权与自定义模型名 # SERVER_API_KEY=sk-xxx SERVER_MODELNAME=VoxCPM1.5 bash start_streaming_tts.sh # 测试(流式返回 wav 分块) curl -X POST http://127.0.0.1:8902/stream_tts \ -H "Content-Type: application/json" \ -d '{"model": "VoxCPM1.5", "text": "你好,这是一个流式语音合成测试。", "request_id": "test-1"}' ``` > VoxCPM 流式合成,边生成边返回 wav chunk,配合 `reference_audio.wav` 控制音色。 > 配置了 `SERVER_MODELNAME` 时请求 body 须带 `model` 字段;配置了 `SERVER_API_KEY` 时须带 `Authorization: Bearer ` 头。 ### RAG · 8903(Embedding + Reranker) ```bash bash start_rag_server.sh # 启用鉴权与自定义模型名 # SERVER_API_KEY=sk-xxx SERVER_MODELNAME=Qwen3-Embedding-0.6B bash start_rag_server.sh python3 test_rag.py ``` ### Image Gen · 8904 ```bash LOCAL_MODEL_DIR=./models/Tongyi-MAI/Z-Image-Turbo SPECIFIC_GPU=3 bash start_image_gen.sh # 启用鉴权与自定义模型名 # SERVER_API_KEY=sk-xxx SERVER_MODELNAME=Z-Image-Turbo bash start_image_gen.sh # 测试 curl -X POST http://127.0.0.1:8904/generate \ -H "Content-Type: application/json" \ -d '{"model": "Z-Image-Turbo", "prompt": "一只橘猫坐在窗台上,阳光洒落", "width": 1024, "height": 1024, "return_format": "base64"}' \ | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'成功:{d.get(\"success\")} 尺寸:{d.get(\"width\")}x{d.get(\"height\")} 耗时:{d.get(\"elapsed_seconds\",\"?\")}s')" ``` > Z-Image-Turbo 基于 Diffusers,**9 步推理**生成 1024×1024 图片,`return_format=base64` 直接返回内联数据。 --- ## 三、本地端口映射(开发调试) 将远程端口映射到本地,用 `http://localhost:8900` 直连远程服务: ```bash # 一次性映射全部端口 ssh -fN -o ServerAliveInterval=60 -o ServerAliveCountMax=3 \ -L 8900:0.0.0.0:8900 -L 8901:0.0.0.0:8901 -L 8902:0.0.0.0:8902 \ -L 8903:0.0.0.0:8903 -L 8904:0.0.0.0:8904 \ @ -p ``` 验证映射(HTTP 200 即通): ```bash for p in 8900 8901 8902 8903 8904; do curl -o /dev/null -s -w "$p: %{http_code}\n" http://localhost:$p/health done ``` --- ## 四、停止服务 ```bash for p in 8900 8901 8902 8903 8904; do kill $(lsof -t -i:$p); done ``` --- ## 五、接入 Agent 四个本地服务(ASR / TTS / RAG / ImageGen)在 Agent 的 `env_config.json` **`models` 列表中注册**(设置 → 环境变量 → LLM 模型列表,或直接编辑 `src/agent/config/env_config.json`),`base_url` 指向本地映射端口,`api_key` 留空(对应服务端未启用鉴权)。Agent 运行时按 `model` 字段匹配取得服务地址: | Agent 能力 | 模型列表条目 | 字段示例 | |-----------|-------------|----------| | 语音识别 | `name: "ASR 语音识别"` | `model: "Qwen3-ASR-1.7B"`, `base_url: "http://localhost:8901"`, `api_key: ""` | | 语音合成 | `name: "TTS 语音合成"` | `model: "VoxCPM1.5"`, `base_url: "http://localhost:8902"`, `api_key: ""` | | 知识库检索 | `name: "RAG 检索"` | `model: "Qwen3-Embedding-0.6B"`, `base_url: "http://localhost:8903"`, `api_key: ""` | | 图像生成 | `name: "图像生成"` | `model: "Z-Image-Turbo"`, `base_url: "http://localhost:8904"`, `api_key: ""` | > 💡 若服务端部署时设置了 `SERVER_API_KEY` / `SERVER_MODELNAME`,请把模型条目中的 `api_key` 与 `model` 改成与之一致,Agent 发出的请求会携带 `Authorization: Bearer ` 与 `model` 字段。 > > 💡 不必自建本服务,Agent 也支持任何 **OpenAI 兼容 API**(云端 Qwen / DeepSeek / OpenAI 等),填入 `base_url` + `api_key` 即可。