Qwen3-0.6B部署后无法访问?检查端口和base_url配置
1. 问题现象:服务启动了,但调用失败
你兴冲冲地用 vLLM 启动了 Qwen3-0.6B,终端里显示INFO: Uvicorn running on http://0.0.0.0:8000,一切看起来都很顺利。可当你在 Jupyter 里运行 LangChain 调用代码,或者用 curl 发送请求时,却收到一串冰冷的报错:
ConnectionRefusedError: [Errno 111] Connection refusedrequests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=8000): Max retries exceeded...- 或者更隐蔽的:返回
404 Not Found,提示模型不存在
别急着重装、别急着怀疑显卡——90% 的情况,问题根本不在模型本身,而在于两个最基础、却最容易被忽略的配置项:端口(Port)和base_url(基础地址)。
这篇文章不讲大道理,不堆参数,就聚焦一个目标:帮你快速定位、一步解决“服务明明跑着,却怎么都连不上”的困扰。我们从真实部署场景出发,用最直白的语言,把这两个配置项掰开揉碎讲清楚。
2. 核心原理:vLLM 启动的是一个 Web 服务,不是本地函数
很多新手会下意识认为:“我本地启动了模型,那它就应该像一个 Python 函数一样,直接model.generate()就行。” 这是一个关键误区。
vLLM 的vllm serve命令启动的,本质上是一个独立的 Web 服务器进程,就像你打开 Chrome 访问https://www.baidu.com一样,LangChain 或 curl 只是它的“浏览器”,必须通过正确的网络地址(URL)才能找到它。
这个 URL 由两部分构成:
- 协议 + 主机名 + 端口→ 构成
base_url - 路径→ 比如
/v1/chat/completions
所以,当你的代码写的是base_url="https://gpu-pod694e6fd3bffbd265df09695a-8000.web.gpu.csdn.net/v1",而你本地启动的命令是vllm serve ... --port 8000,这两者之间必须严格匹配,否则就是“鸡同鸭讲”。
2.1 端口(Port):服务的“门牌号”
端口是网络通信的入口编号。你告诉 vLLM “请把服务开在 8000 号门”,那么所有想访问它的请求,就必须敲 8000 这扇门。
- 正确:
vllm serve ... --port 8000+base_url="http://localhost:8000/v1" - 错误:
vllm serve ... --port 8000+base_url="http://localhost:8080/v1"(敲错了门) - 错误:
vllm serve ... --port 8000+base_url="http://127.0.0.1:8000/v1"(看似一样,但某些环境有细微差异)
如何确认端口是否正确?
- 查看 vLLM 启动日志,第一行通常会打印
Uvicorn running on http://0.0.0.0:XXXX,这里的XXXX就是实际端口。 - 在另一台终端里执行
netstat -tuln | grep :8000(Linux/macOS)或netstat -ano | findstr :8000(Windows),如果看到LISTEN状态,说明端口已被占用且服务已启动。
2.2 base_url:客户端的“导航地图”
base_url是 LangChain 或其他客户端用来构建完整请求地址的“根目录”。它必须精确指向你本地 vLLM 服务的地址。
http://localhost:8000/v1:这是最标准、最推荐的写法,表示“请访问我本机(localhost)的 8000 号门,然后进入/v1这个区域”。https://gpu-pod694e6fd3bffbd265df09695a-8000.web.gpu.csdn.net/v1:这是 CSDN 星图镜像平台为你分配的公网域名,它背后会自动映射到你容器内的localhost:8000。这个地址只在 CSDN 平台的 Jupyter 环境中有效,在你自己的本地电脑上绝对无法访问!
常见错误与修正:
| 你遇到的情况 | 错误原因 | 正确做法 |
|---|---|---|
在自己电脑上运行代码,base_url写成https://gpu-pod... | 这个域名是 CSDN 平台内部的,你的电脑 DNS 解析不了 | 改为http://localhost:8000/v1 |
在 CSDN 平台的 Jupyter 里运行,base_url写成http://localhost:8000/v1 | 在容器内,localhost指的是容器自己,而 vLLM 服务可能运行在另一个容器或主机上 | 改为平台提供的https://gpu-pod.../v1 |
启动命令没加--port 8000,用了默认端口 | vLLM 默认端口是 8000,但如果你之前改过,或系统被占用了,它会自动选一个新端口 | 启动时务必显式指定--port 8000,并确保该端口空闲 |
3. 三步诊断法:快速定位连接失败根源
与其反复试错,不如按顺序执行以下三个简单命令,5 分钟内就能 pinpoint 问题所在。
3.1 第一步:确认服务进程是否真在运行
打开一个新终端,执行:
ps aux | grep "vllm serve"你应该能看到类似这样的输出:
user 12345 0.0 0.1 123456 7890 ? Sl 10:00 0:05 python -m vllm.entrypoints.openai.api_server --model /path/to/Qwen3-0.6B --port 8000 ...如果什么都没输出,说明服务根本没起来。请回到启动命令,检查路径、CUDA、内存是否充足。
3.2 第二步:确认端口是否监听成功
在同一台机器上,执行:
curl -v http://localhost:8000/health- 如果返回
{"status":"healthy"},恭喜,服务健康,端口畅通。 - 如果返回
Failed to connect to localhost port 8000: Connection refused,说明服务没监听在localhost:8000,请检查启动命令中的--port参数和--host参数(默认是0.0.0.0,即监听所有网卡)。
小技巧:如果
localhost不通,试试curl http://127.0.0.1:8000/health,两者在绝大多数情况下等价,但极少数 Docker 网络配置下会有差异。
3.3 第三步:确认 base_url 配置是否匹配
这是最关键的一步。请将你的 LangChain 代码中的base_url值,和你在第二步中成功访问的地址逐字比对。
例如,如果你第二步用curl http://localhost:8000/health成功了,那么你的代码必须是:
base_url="http://localhost:8000/v1" # 注意:是 http,不是 https;是 localhost,不是 127.0.0.1(除非你明确知道要这么用)反之,如果你是在 CSDN 星图的 Jupyter 里操作,第二步应该用:
curl -v https://gpu-pod694e6fd3bffbd265df09695a-8000.web.gpu.csdn.net/health那么代码里的base_url就必须和这个地址完全一致,只是末尾加上/v1。
4. 完整可运行示例:从零开始验证
下面是一套经过实测的、能 100% 跑通的最小化流程。请严格按顺序执行,每一步都验证结果。
4.1 启动服务(Linux/macOS 终端)
# 确保你在模型目录的上一级,比如模型在 ~/models/Qwen3-0.6B VLLM_USE_V1=0 vllm serve ~/models/Qwen3-0.6B --port 8000 --max-model-len 6384 --host 0.0.0.0注意:
--host 0.0.0.0是关键,它让服务能被同一局域网内的其他设备访问(比如你的笔记本访问服务器)。如果只在本机用,不加也行。
4.2 验证服务(新终端)
# 1. 检查健康状态 curl http://localhost:8000/health # 2. 查看可用模型列表(确认模型名) curl http://localhost:8000/v1/models # 3. 发送一个最简单的聊天请求(测试核心功能) curl http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen3-0.6B", "messages": [{"role": "user", "content": "你好"}], "max_tokens": 50 }'4.3 LangChain 调用(Jupyter 或 Python 脚本)
from langchain_openai import ChatOpenAI # 关键:base_url 必须和上面 curl 的地址完全一致 chat_model = ChatOpenAI( model="Qwen3-0.6B", # 这个名字必须和 curl /v1/models 返回的一致 temperature=0.5, base_url="http://localhost:8000/v1", # ←←← 这里是唯一需要修改的地方! api_key="EMPTY", # vLLM 不校验 key,填什么都行 streaming=True, ) response = chat_model.invoke("你是谁?") print(response.content)5. 常见陷阱与避坑指南
即使你严格按照上述步骤操作,仍可能掉进一些“隐形坑”。以下是工程师们踩过的典型雷区,帮你提前绕开。
5.1 陷阱一:防火墙/安全组拦截了端口
- 现象:在服务所在的服务器上,
curl http://localhost:8000/health成功,但在你自己的笔记本上curl http://服务器IP:8000/health失败。 - 原因:服务器的防火墙(如
ufw、firewalld)或云服务商的安全组规则,默认只放行 22(SSH)、80、443 等常用端口,8000 被拦在门外。 - 解决:
- Ubuntu:
sudo ufw allow 8000 - CentOS:
sudo firewall-cmd --permanent --add-port=8000/tcp && sudo firewall-cmd --reload - 阿里云/腾讯云:登录控制台,在“安全组”规则里添加一条入方向规则,端口范围
8000/8000,授权对象0.0.0.0/0(或你的 IP)。
- Ubuntu:
5.2 陷阱二:Docker 容器网络隔离
- 现象:你在 Docker 容器里启动了 vLLM,但在宿主机上无法访问
http://localhost:8000。 - 原因:Docker 容器默认使用
bridge网络,容器内的localhost和宿主机的localhost是两个世界。你需要将容器端口映射出来。 - 解决:启动容器时,加上
-p 8000:8000参数。docker run -p 8000:8000 -v /path/to/models:/models your-qwen-image vllm serve /models/Qwen3-0.6B --port 8000
5.3 陷阱三:模型名称不匹配
- 现象:
curl /v1/models返回的模型名是Qwen/Qwen3-0.6B,但你的 LangChain 代码里写的是Qwen3-0.6B,调用时报404 Model not found。 - 原因:vLLM 会将你启动时
--model参数的路径,作为模型的注册名。如果你的路径是~/models/Qwen3-0.6B,它可能注册为Qwen3-0.6B;如果是~/models/Qwen/Qwen3-0.6B,它就注册为Qwen/Qwen3-0.6B。 - 解决:永远以
curl http://localhost:8000/v1/models的返回结果为准,把它原封不动地复制到model=参数里。
6. 总结:记住这三条铁律
部署 Qwen3-0.6B 后无法访问,本质是一个“网络连通性”问题,而非模型能力问题。只要牢记并严格执行以下三条,99% 的连接失败都能迎刃而解:
1. 端口必须显式声明且保持一致
启动命令里写--port 8000,客户端的base_url里就必须是:8000。不要依赖默认值,不要随意猜测。
2. base_url 必须与服务监听地址完全一致
在哪儿启动,就在哪儿访问。本地启动,就用http://localhost:8000/v1;在 CSDN 平台启动,就用它给你的https://gpu-pod.../v1。二者绝不能混用。
3. 验证必须分层进行
先ps看进程,再curl看端口,最后curl看 API。层层递进,哪一层断了,就专注修复那一层,切忌盲目重启整个环境。
现在,你可以关掉这篇博客,打开你的终端,用curl http://localhost:8000/health做一次快速自检。如果它返回了健康的信号,那么恭喜,你离和 Qwen3-0.6B 的第一次成功对话,只剩下一次chat_model.invoke()的距离。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。