拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Qwen接入与本地部署实战:三类默认链接一次讲清

Qwen接入与本地部署实战:三类默认链接一次讲清

把 Qwen 跑通,说难不难,说简单也不简单。我见过不少人卡在一个问题上:明明照着教程写的代码,请求发出去就是不通,要么 Connection refused,要么 404 Not Found,排查一圈下来,问题往往出在最不起眼的东西上——默认链接。这里的“默认链接”不是一个神秘入口,而是三样东西:官方 API 的默认端点地址、本地部署后服务的默认监听地址、模型文件默认的下载来源。很多人把这三层混在一起,导致网上那些教程越看越乱。这篇文章我把实际接入和部署 Qwen 的经验整理成一份可以直接抄作业的笔记,顺便把微调、流式输出、多模态这些经常被一起提起的场景也串起来讲。适合刚接触大模型 API 的开发者,也想覆盖那些准备在自己电脑上跑本地模型的玩家。

1. “默认链接”到底指什么:先分清三个层面

1.1 官方 API 接入层的默认端点

Qwen 的官方 API 托管在阿里云百炼(DashScope)平台上,所有请求都打向一个固定的网关地址。很多人第一次用的时候会困惑,因为网上教程里出现过好几个不同的 URL,有写 dashscope.aliyuncs.com/api/v1 的,有写 dashscope.aliyuncs.com/compatible-mode/v1 的,还有直接写 model scope 域名当 API 用的,全是错的。

先说结论:DashScope 原生接口的默认地址是 https://dashscope.aliyuncs.com/api/v1,但我不推荐直接用这个,因为它的请求格式是 DashScope 私有协议,跟 OpenAI 的格式不一样,很多通用工具接不了。

推荐用 OpenAI 兼容模式的默认端点:https://dashscope.aliyuncs.com/compatible-mode/v1。这个地址的行为和 OpenAI 官方 API 完全一致,chat/completions、embeddings 这些接口都能直接复用,市面上绝大多数大模型工具链都认这个协议。也就是说,你只要把原来填 OpenAI 地址的地方换成这个链接,再把 api_key 换成 DashScope 的 key,其他代码一行都不用改。

实际项目里我一般把 endpoint 和 api_key 都放到环境变量里,而不是写死在代码里,原因后面会讲。

1.2 本地部署后的默认服务地址

本地部署是另一个高频场景。Qwen 的开源模型权重发布后,大家会用各种推理框架把模型跑起来,每个框架都有一个“默认链接”,这个链接指的是服务启动后监听的 HTTP 地址,也就是客户端去访问的入口。

这里有一个必须养成的习惯:区分“本地回环地址”和“局域网访问地址”。

  • Ollama 默认监听 http://localhost:11434,API 路径是 /api/chat,另有一个兼容 OpenAI 的 /v1/chat/completions。
  • vLLM 默认监听 http://localhost:8000,OpenAI 兼容接口路径是 /v1。
  • llama.cpp 的 server 子命令默认监听 http://localhost:8080。
  • LLaMA-Factory 的 webui 默认监听 http://localhost:7860,启动 API 服务后默认 8000。

localhost 只代表“本机访问”,如果想让局域网里另一台机器调用这个模型服务,必须让服务监听 0.0.0.0,并改成对应网卡的 IP。很多人部署完以后在另一台机器上访问不了,十有八九就是忘了改监听地址。

1.3 模型文件下载的默认来源

第三个层面的“默认链接”是模型权重去哪下。Qwen 开源模型的官方发布渠道有两个:HuggingFace 和 ModelScope。对国内用户来说,ModelScope 的下载速度和稳定性好很多,我基本一直用它。

这里要特别提醒一件事:不要在不知名的第三方网盘、QQ 群文件或者来路不明的镜像站下载模型压缩包。你根本不知道里面被塞了什么,模型反序列化的时候万一加载到恶意权重,后果很难追查。认准 ModelScope 或者 HuggingFace 上的官方组织账号,比如 Qwen 官方账号、阿里云 ModelScope 官方账号下的仓库。

另外,ModelScope 上每个模型仓库页面的“文件”标签页里,会列出所有可用文件。比如你想下载量化版,就要找名字里带 GGUF、AWQ、GPTQ、IQ2_M 这类标识的文件。像“qwen ud-iq2_m下载”这个需求,指的就是 Qwen 某个 GGUF 量化版本,具体文件名通常是 qwen2.5-7b-instruct-q4_k_m.gguf 这样。

2. 官方 API 的接入实操:把默认链接变成能跑通的请求

2.1 注册、密钥与最小请求

用官方 API 只需要三步:注册阿里云账号并开通百炼、创建一个 API Key、然后拿这个 Key 去请求默认端点。

创建 API Key 之后,建议立刻把 Key 复制到本地环境变量里:

export DASHSCOPE_API_KEY="sk-xxxxxxxxxxxxxxxx"

然后用 curl 做一个最小验证。我自己每次换新环境都先跑这段,确认网络、密钥、端点都没问题再往上写业务代码:

curl https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \ -H "Authorization: Bearer $DASHSCOPE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "qwen-plus", "messages": [ {"role": "system", "content": "你是一个简洁的助手"}, {"role": "user", "content": "用一句话说明什么是默认链接"} ] }'

返回里会有一个 choices 数组,里面带 content 字段,能看到文本就说明整个链路通了。这一步能排除掉 80% 的配置问题。

2.2 模型名称与上下文的对应关系

不少人在这一步栽跟头——endpoint 写对了,key 也没问题,却报 Model not exist。原因很简单:请求体里的 model 名字和你在百炼控制台开通的模型不一致。

官方 API 上常见的模型名有:

模型标识适用场景默认上下文长度
qwen-turbo高频、低成本对话1M 上下文(部分版本)
qwen-plus通用对话,性价比均衡1M 上下文(部分版本)
qwen-max复杂推理、高质量生成32K 或更高
qwen3-235b-a22b-instruct追求极强推理能力128K 左右

我的经验是:日常聊天和快速验证用 qwen-turbo,写代码、做分析用 qwen-plus,复杂任务再不满足再上 qwen-max。模型名必须区分大小写,qwen-Plus 这种写法会直接报错。

另外,请求里的 max_tokens 参数只控制生成的 token 上限,不是输入的总长度。输入长度由模型上下文窗口和当前请求的 messages 总长度共同决定,超了会报 InvalidParameter 或者 context length exceeded。遇到这个错误,要么手动裁剪历史消息,要么把请求拆成多轮摘要后再送进去。

2.3 OpenAI SDK 直连:一套代码通吃

因为 Qwen 的 OpenAI 兼容端点存在,你完全不需要为了接 Qwen 再学一套 SDK。直接用 openai 这个 Python 包,把 base_url 指过去就行:

from openai import OpenAI client = OpenAI( api_key="sk-xxxxxxxxxxxxxxxx", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" ) response = client.chat.completions.create( model="qwen-plus", messages=[ {"role": "system", "content": "你是资深编程助手"}, {"role": "user", "content": "用 Python 写一个快速排序"} ] ) print(response.choices[0].message.content)

这个模式的好处是迁移成本极低。如果你之前用的是 OpenAI、DeepSeek、智谱这类模型的服务,只需要把 base_url 和 api_key 换成 Qwen 的,模型名也换掉,其他业务代码基本不用动。Spring AI 这类 Java 生态框架里也同理,只需要改配置文件里的 base-url 和 api-key 属性。

这也就是为什么市面上会出现“mac claude cli 用 qwen key”这类玩法——因为 Claude CLI 底层也支持自定义模型的 OpenAI 兼容端点,把 base_url 指向 Qwen 的兼容端点,就能用 Qwen 跑命令行聊天。虽然是偏门用法,但原理就是替换默认链接。

3. 本地部署时的默认链接与端口踩坑

3.1 Ollama 跑 Qwen:最省事的路径

Ollama 是把 Qwen 跑在本机最简单的方式,一条命令就能把模型拉下来并启动服务:

ollama run qwen2.5:7b

运行后本地就有了一个默认链接 http://localhost:11434。Ollama 自带的客户端会直接走这个地址,所以你在终端里怎么聊都行。但如果想从自己的代码里调它,有两个 API 路径需要知道:

  • 原生接口:POST http://localhost:11434/api/chat
  • OpenAI 兼容接口:POST http://localhost:11434/v1/chat/completions

我个人更推荐用 /v1 这个路径,这样和云端 API 的代码写法完全一致。调用前先确认一下模型是否已经拉取成功,用 ollama list 查看本机模型列表,模型名一定要写全,比如 qwen2.5:7b,少写 tag 可能默认拉到别的版本。

如果想让局域网内其他设备访问这个服务,需要设置环境变量让 Ollama 监听所有网卡:

export OLLAMA_HOST=0.0.0.0:11434

改完重启 Ollama 服务,然后用 http://192.168.x.x:11434 访问。需要注意:这样会把模型服务暴露给整个局域网,如果有敏感数据建议加一层 API 网关做鉴权,别裸奔。

3.2 vLLM 部署:生产环境的标准姿势

当并发上来、需要稳定吞吐时,Ollama 就不够看了。这时候我会上 vLLM,它利用 PagedAttention 做显存管理,推理速度和吞吐都比朴素方案好不少。

vLLM 启动 Qwen 的命令很简单:

vllm serve Qwen/Qwen2.5-7B-Instruct --host 0.0.0.0 --port 8000

启动完成后,默认链接就是 http://localhost:8000/v1,可以直接用前面 OpenAI SDK 的写法访问,base_url 改成 http://localhost:8000/v1,model 改成 Qwen/Qwen2.5-7B-Instruct。

这里有几个参数我会根据显存情况调整:

  • --max-model-len:控制最大上下文长度。如果显存紧张,设置成 8192 或 4096 可以省不少显存;如果显存充足,就按模型支持的窗口来。
  • --gpu-memory-utilization:设置显存利用率,默认 0.9。跑 7B 模型时如果总显存只有 8G,可以把利用率降到 0.7 左右,避免启动时 OOM。
  • --quantization:显存不够时配合 AWQ、GPTQ 量化模型使用。

实际上 vLLM 启动失败的原因,80% 是 7B 模型的非量化版本在 8G 显存上跑不起来。遇到 CUDA out of memory,可以直接换量化版模型,或者在启动命令里砍掉最大上下文长度。Windows 11 上部署 Qwen 也不要慌,只要 CUDA 和显卡驱动匹配好,流程和 Linux 基本一致。

3.3 LoRA 微调后的模型怎么挂回默认链接

现在大家都在玩微调,尤其是 LoRA 这种轻量方案。热搜里“lora微调实战教程qwen”对应的场景,其实就是用 LLaMA-Factory 对 Qwen 做 LoRA 微调,然后把微调后的权重部署成一个服务。

流程上分四步:

  1. 准备数据集,格式是 JSON,每条包含 instruction、input、output 三个字段。
  2. 用 LLaMA-Factory 训练 LoRA,命令大致长这样:
llamafactory-cli train \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --dataset alpaca_zh \ --finetuning_type lora \ --lora_rank 8 \ --output_dir ./qwen_lora
  1. 把 LoRA 权重和基座模型合并成独立权重:
llamafactory-cli export \ --model_name_or_path Qwen/Qwen2.5-7B-Instruct \ --adapter_name_or_path ./qwen_lora \ --export_dir ./qwen_merged
  1. 用 vLLM 或 Ollama 把合并后的目录启动起来。

这里我想强调一个容易忽略的点:微调完的模型如果不合并 LoRA 权重就直接用 vLLM 加载,要么报错,要么行为还是基座模型的样子。原因在于推理框架默认不识别额外的 LoRA adapter 路径,必须先把 LoRA 合并进完整权重。用 LLaMA-Factory 的 export 命令把 adapter 合并掉再部署,能省掉一堆玄学问题。

合并后的模型启动后,默认链接依旧和普通模型一样,只是你要把 model 名称改成新目录名。这也是很多人“明明微调完了,但接口回复完全没变化”的根源——请求里用的还是原来的 qwen-plus 云端模型名,压根没有指向本地微调服务。

4. 热门场景接入:把这几个默认链接真正用起来

4.1 流式输出与中断处理:SSE 的实战细节

大模型响应慢,如果不用流式输出,用户会以为页面卡死了。SSE(Server-Sent Events)是这里的主流方案,OpenAI 兼容接口下只要加 stream=true 就能开启:

from openai import OpenAI client = OpenAI( api_key="sk-xxx", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" ) stream = client.chat.completions.create( model="qwen-plus", messages=[{"role": "user", "content": "讲一个三句话的冷笑话"}], stream=True ) for chunk in stream: delta = chunk.choices[0].delta.content if delta: print(delta, end="", flush=True)

实际做业务时,流式输出要配合前端的 AbortController 来支持“停止生成”。比如用户在界面上点“停止”,前端发送一个 abort 信号,HTTP 连接断开,后端捕获到这个异常后要立刻停止生成逻辑并释放资源。

这个环节最容易翻车的是后端:客户端断开后,生成循环还在跑,白白浪费 token。正确的做法是在生成循环里判断请求上下文是否已被取消,Python 里可以用 asyncio 的 CancelledError 或者检查 response.is_disconnected。SSE 本身格式也比较苛刻,每段数据必须以 data: 开头,以两个换行符结尾,自己拼格式很容易漏掉结尾符,建议直接使用成熟的 SSE 库。

4.2 多模态模型默认链接:Qwen Image 与 ComfyUI

Qwen 系列不止文本模型,还有图像理解和生成的模型,比如 qwen image 2.1。在 ComfyUI 里接入这类多模态模型时,套路和文本模型完全不同。

文本模型只要填 base_url 和 api_key;图像模型在 ComfyUI 里通常会走自定义节点,节点里要填的是三个东西:

  • 模型请求链接:通常是 DashScope 的视觉模型端点,或者本地部署服务的地址。
  • API Key:云端 API 的密钥,或本地的空值。
  • 模型名:比如 qwen-image-2.1 这类标识。

ComfyUI 的工作流本质上是一个个节点的连接,图像生成节点拿到提示词后,把文本和图片数据一起 POST 到模型链接,再把返回的图像数据解码成节点输出。这里最常踩的坑是图片上传时的编码格式,有的节点要求 base64,有的要求二进制流,传错了会报 400。建议先在代码里单独测通一次 API,再去接 ComfyUI,否则你分不清是工作流问题还是模型接口问题。

4.3 大模型知识抽取与提示词工程

另一个经常被问到的场景是知识抽取框架,比如 OneKE 这类基于 Qwen 的知识抽取工具。这类框架本质上是在 Qwen 的默认链接之上封装了一套提示词模板和结构化输出协议。

用这一类框架时,“默认链接”的作用体现在:你可以在配置里填入任意兼容 OpenAI 协议的端点,云端 API 填 DashScope 地址,本地部署就填 http://localhost:8000/v1。框架只认这个链接,它不关心背后是云端还是你电脑上的显卡。所以你会发现,同一套知识抽取代码,换个 base_url 就能在云和本地之间无缝切换。

这也是我想强调的观点:默认链接的价值在于“协议标准化”。只要接口协议统一,模型、算力、部署位置都可以被替换。理解了这一点,就理解了大模型应用开发的半壁江山。

5. 常见问题、报错与排查速查表

下面这张表是我在实际接入和部署过程中反复用到的排查清单,覆盖了从云端 API 到本地部署最常见的坑:

现象可能原因排查与解决
401 InvalidApiKeyAPI Key 错误或已失效检查环境变量是否加载,到百炼控制台重新生成 Key
404 Model not exist模型名错误或未开通核对模型标识的大小写,确认控制台已开通对应模型
404 Not Foundendpoint 路径写错确认是 compatible-mode/v1 还是原生 api/v1
Connection refused本地服务没起来或端口不对检查进程是否存活,端口是否被占用,确认监听地址
Connection timed out网络不通或跨网段访问先 curl localhost 测本机,再确认防火墙与监听 IP
context length exceeded输入太长超出上下文窗口截断历史消息、增加摘要,或换上下文更大的模型
CUDA out of memory显存不足换量化模型,调低 max-model-len,或降 gpu-memory-utilization
流式输出不显示SSE 格式不对或缓存确认 data: 前缀和空行,关闭前端代理缓冲区
微调后回答没变化请求仍指向云端旧模型检查 base_url 和 model 名是否指向本地微调服务

5.1 环境变量统一管理链接

我强烈建议所有 endpoint、api_key、model name 都用环境变量管起来,而不是写死。项目里通常配一个 .env 文件:

QWEN_API_KEY=sk-xxxxxxxx QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 QWEN_MODEL=qwen-plus

Python 里用 pydantic-settings 或者 python-dotenv 加载。这样做的最大好处是:代码在不同环境间迁移时,不需要改业务逻辑,只改环境变量。我见过很多事故都是因为有人在代码里硬编码了一个失效的 key,或者把测试环境的地址带到了生产环境。

5.2 几个容易忽略的细节

第一,API Key 绝对不要放到前端代码里。浏览器里所有内容都是公开的,key 一旦泄露就会被盗刷。正确做法是前端走自己的后端,由后端持有 Key 再转发到 Qwen 接口。

第二,本地部署时 OLLAMA_HOST 只改环境变量还不够,Windows 上要确认防火墙是否放行了对应端口。Windows 11 上部署 Qwen 时,如果局域网访问不了,先检查防火墙入站规则,再检查服务是否真的监听在 0.0.0.0。

第三,量化模型文件名里的 IQ2_M、Q4_K_M 不是随便起的。它代表不同的量化精度,模型体积越小、精度损失越大。如果你的机器显存刚够 7B 模型,推荐从 q4_k_m 开始试,它能兼顾体积和效果。q2 系列虽然更小,但生成质量下降会比较明显,不是迫不得已别选。

第四,用 LLaMA-Factory 做 LoRA 微调时,lora_rank 不是越大越好。8 到 16 对大多数任务已经够用,再大不仅训练慢,还可能过拟合。微调数据集质量比数量重要,几百条高质量指令数据的效果往往好过几万条脏数据。

6. 一条链路串起来看:从本地模型到云端 API 的完整选择

写到最后,我分享一个实际项目里通用的决策思路:同一套业务代码,先跑通云端 API,再考虑本地部署加缓存。云端的好处是零运维、模型版本新、上下文窗口大,缺点是按量付费,高频调用成本会涨。本地部署的好处是数据不出内网、无按量费用,缺点是要有 GPU 机器,还要自己做监控、告警、并发控制。

我的做法是在代码里都走 OpenAI 兼容协议,只留一个配置开关,环境变量指向云端就调云端,指向本地 vLLM 就调本地。业务层完全无感。这样既可以在开发阶段用云端快速联调,又能在数据敏感的场景一键切到本地。如果你也在做类似的项目,不妨今天就试一下:把代码里的 base_url 抽出来放到环境变量,再花十分钟用 Ollama 或者 vLLM 把 Qwen 跑起来,你会发现自己已经同时拥有了两套可切换的大模型运行环境。

返回列表