如果你想在一台没有独立显卡(或者只有一张老显卡)的机器上,跑通一套**完全离线**的「文档问答」环境——本地把文字转成向量、本地存起来、本地检索、本地生成回答,不调用任何在线大模型服务——这篇文章把整个过程从头到尾写了一遍。
实测机器:i5-10400F + 32GB 内存 + GTX 1050 Ti(4GB 显存)。显卡是 2016 年的 Pascal 架构,4GB 显存放到今天属于”最低配”,所以下面所有选型和参数都以这个配置为边界——如果你的显卡比这个好,门槛只会更低。
全文按「先搞懂要做什么 → 检查机器 → 一步步装 → 验证 → 避坑」的顺序组织,每一步都给出**预期输出**,你可以随时对照确认自己做对了没有。
一、先搞清楚要搭什么
1.1 为什么需要两个组件
目标很简单:让 AI 回答你文档里的问题。
但直接把一整份文档丢给模型是行不通的——两个原因:一是文档可能几十万字,超出模型的上下文窗口;二是即使塞得进去,模型也会在长文本里”走神”,找不准重点。
标准解法叫 RAG(检索增强生成),拆成两个独立的能力:
| 能力 | 做什么 | 本项目用什么 |
|---|---|---|
| 向量化 + 检索 | 把文档切块、转成「向量」(一串数字,代表文字的语义),存进专门的数据库;提问时把问题也转成向量,找出语义最接近的几块 | Qdrant(存向量)+ bge-m3(算向量) |
| 生成回答 | 拿到检索出的几块原文,连同问题一起交给对话模型,让它基于这些原文作答 | qwen3:4b(对话模型) |
所以需要两个模型:一个专门把文字转成向量(嵌入模型),一个负责对话(对话模型)。它们不一样,别搞混——后面第五节会专门讲这个容易踩的认知坑。
至于数据库,普通的 MySQL 做不了”语义相似度搜索”(它只能做精确匹配和模糊匹配),所以需要专门的向量库。
1.2 为什么选本地部署
调 RAG 链路要反复试参数:切片多大、检索几条、相似度阈值多少。走在线 API 的话,每改一版都要等网络、受额度限制、还可能被计费;本地跑则是”改一版立刻验证”,迭代快得多。
代价是本地模型能力弱于在线大模型——但作为技术验证环境,够用了。
1.3 架构:算力留在本机,存储放到服务器

分工是本机管算,服务器管存:
- 本机(Windows):Ollama 负责两件事——用
bge-m3把文本转成向量,用qwen3:4b生成回答。因为这两件事都要用显卡,只有在有显卡的机器上才能跑。 - 服务器(Linux):Qdrant 负责向量的存储和相似度检索。它要常驻、要持久化,扔服务器上不占本机内存。
- 两者之间:走 HTTP(REST)跨机器调用。
如果你只有一台机器,把它们都装在本机也完全可以,只是本机内存会被多占一些。
二、动手前的检查(省下最多时间的 5 分钟)
这一步很容易被跳过,但跳过它可能导致装到一半才发现硬件不支持。先花五分钟确认四件事。
2.1 显卡能不能被 CUDA 用
打开命令行(Win + R 输入 cmd),执行:
nvidia-smi
预期输出:一张表格,包含显卡型号、驱动版本、显存大小。
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 581.57 Driver Version: 581.57 CUDA Version: 13.0 |
|-----------------------------------------+------------------------+----------------------+
| 0 NVIDIA GeForce GTX 1050 Ti | 00000000:01:00.0 | N/A |
| N/A 58C P8 N/A / 75W | | 310MiB / 4096MiB |
+-----------------------------------------+------------------------+----------------------+
三个关键信息:
GTX 1050 Ti—— 显卡型号,后面判断架构要用Driver Version: 581.57—— 驱动版本,**这是本次最容易出问题的点**4096MiB—— 显存总量,决定了能跑多大的模型
如果提示 nvidia-smi 不是内部或外部命令,说明没装显卡驱动,先去 NVIDIA 官网装。如果 nvidia-smi 正常但驱动版本很老(比如 5xx 以下),先别急着装 Ollama——第 7 节会讲为什么。
2.2 4GB 显存能跑多大的模型(这个必须算清楚)
很多人以为”显存越大就能跑越大的模型”是个模糊的事,其实可以估出来。看一个粗略的公式:
能放的参数量 ≈ 可用显存 ÷ 每参数字节数
每参数字节数(Q4 量化,最常用的压缩级别):
FP16 精度 约 2.0 字节/参数
Q8 量化 约 1.0 字节/参数
Q4 量化 约 0.6 字节/参数 ← 日常用的就是这个
代入本机:
显存总量 4.0 GB
系统占用 约 0.7 GB(桌面环境、驱动)
实际可用 约 3.3 GB
3.3 GB ÷ 0.6 ≈ 5.5B 参数
结论:4GB 显存下,4B 参数以内的模型可以整个放进显存,跑得飞快;再大就要把一部分”卸载”到内存里,速度断崖式下跌。
这条推论直接决定了后面第五节的所有选型——有了这个计算,你看到”4~6GB 属于能跑但要等”就明白为什么了,而不是记住一个结论。
2.3 磁盘空间够不够
模型文件很大。本机 C 盘当时只剩 3.5GB,装两个模型就满了。建议提前把 Ollama 的模型目录设到空间大的盘(第四节会讲怎么设)。
2.4 网络能不能连通
这一步很现实——国内的网络环境下,几个站点连通性不一样:
| 站点 | 用途 | 实测 |
|---|---|---|
registry.ollama.ai |
下载模型 | 直连正常 |
cn.download.nvidia.com |
下载显卡驱动 | 可用 |
github.com |
下载 Qdrant | 直连被断,用 gh-proxy.com 镜像 |
先测一下,免得后面卡在下载上:
curl -I https://registry.ollama.ai # 返回 200/301 就正常
curl -I https://github.com # 超时就是被断了
三、第一步:装 Qdrant(向量库)
3.1 为什么选它
选型逻辑很简单:一个测试环境不该引入半套分布式系统。
对比过 Milvus——它依赖 etcd、MinIO 等一堆组件,为了一次验证拉起这么多东西太重。Qdrant 是单进程,一个二进制文件就能跑,自带 Web 面板和 REST API,对测试场景刚好合适。
3.2 下载与安装
注意一个坑:预编译包的下载入口在 GitHub 的 Releases 页面,不在仓库首页。仓库首页只有源码编译的说明,很多人会在这里卡住。
官方发布页:https://github.com/qdrant/qdrant/releases
方式一:Debian / Ubuntu(推荐,交给 systemd 托管)
curl -L -o qdrant.deb https://github.com/qdrant/qdrant/releases/download/v1.19.1/qdrant_1.19.1-1_amd64.deb
sudo dpkg -i qdrant.deb
sudo systemctl start qdrant && sudo systemctl enable qdrant
方式二:单文件二进制(老系统务必选 musl 版)
cd /opt
# x86_64:qdrant-x86_64-unknown-linux-gnu.tar.gz(要求 glibc ≥ 2.33)
# ARM: qdrant-aarch64-unknown-linux-musl.tar.gz
curl -L -o qdrant.tar.gz https://github.com/qdrant/qdrant/releases/download/v1.19.1/qdrant-x86_64-unknown-linux-musl.tar.gz
tar -xzf qdrant.tar.gz
nohup ./qdrant > qdrant.log 2>&1 &
两种文件名的区别是 gnu 和 musl:gnu 版动态链接系统的 C 库,要求 glibc ≥ 2.33;musl 版是静态编译的,不挑系统。**如果你的服务器是 CentOS 7、Debian 10 这类老发行版,直接选 musl 版**,能省掉一个坑。
3.3 验证装好了没有
curl http://localhost:6333/healthz
预期输出:
{"title":"qdrant - vector search engine","version":"1.19.1","commit":"..."}
然后在浏览器打开 http://服务器IP:6333/dashboard,能看到一个 Web 管理面板,说明装好了。
注意:访问根路径 http://IP:6333 会返回 404,这是正常的——面板挂在 /dashboard 子路径下。别以为没装成功。
3.4 端口怎么开
| 端口 | 用途 | 是否需要对外开放 |
|---|---|---|
| 6333 | HTTP REST API + Web 面板 | 是 |
| 6334 | gRPC(集群节点间通信) | 否 |
防火墙和安全组只放行 6333 就够。而且建议按来源 IP 段收紧,不要对 0.0.0.0/0 开放——测试用的向量库没必要让全网都能连。
四、第二步:装 Ollama(模型服务)
4.1 安装
从官网 ollama.com 下载 Windows 安装包。如果 GitHub 直连被断,走 gh-proxy.com 这类公共镜像下载。
装完后 Ollama 会在 11434 端口提供一个本地 HTTP 服务,所有模型调用都走这个端口。
4.2 模型目录迁到空间大的盘
默认模型存在 C 盘的 ~/.ollama/models。如果 C 盘紧张,先把它搬走再下载模型——**顺序反了的话模型会先下到 C 盘**。
# 先停止 Ollama 服务,然后
Move-Item C:\Users\Administrator\.ollama\models\* D:\OllamaModels
setx OLLAMA_MODELS "D:\OllamaModels" # 用户级环境变量,永久生效
验证:重开一个命令行窗口(让环境变量生效),执行 echo %OLLAMA_MODELS%,应输出 D:OllamaModels。
4.3 验证服务正常
ollama list
预期输出:一个表格(可能为空,因为还没拉模型),但有表头 NAME ID SIZE MODIFIED 就说明服务活着。
如果提示 ollama 不是内部或外部命令,说明 PATH 还没刷新——直接写全路径:%LOCALAPPDATA%ProgramsOllamaollama.exe list。
五、第三步:拉取模型
5.1 嵌入模型:bge-m3
ollama pull bge-m3 # 约 1.2GB,从 registry.ollama.ai 直连即可
预期输出:进度条走完,最后显示 success。
然后 ollama list 应该能看到它。
这里有个认知坑要先说清楚:bge-m3 是嵌入模型,不是对话模型。
它只做一件事——把文字转成一串数字(向量)。所以:
- 它不会出现在 Ollama 桌面 App 的 Chat 模型列表里,这是正常的,不用怀疑没装好
- 它不能用来聊天,你问它问题它也不会回答
- 它输出的向量是 1024 维——记住这个数,Qdrant 建集合时要写
size=1024,对不上就存不进去
5.2 先验证嵌入模型能用
curl http://localhost:11434/api/embed -d '{
"model": "bge-m3",
"input": ["今天天气真好", "今天阳光明媚", "股票市场大跌"]
}'
预期输出:embeddings 数组里有 3 个子数组,每个长度是 1024。
要确认它”真的懂语义”,可以算一下余弦相似度:
"今天天气真好" vs "今天阳光明媚" → 0.90 (意思相近,分高 ✓)
"今天天气真好" vs "股票市场大跌" → 0.42 (意思无关,分低 ✓)
这个区分度说明模型可用了。如果两组分数都差不多(比如都是 0.8),那模型肯定有问题。
5.3 对话模型:qwen3:4b
ollama pull qwen3:4b # 约 2.5GB
为什么选 4B?回到第 2.2 节的计算:4GB 显存实际可用约 3.3GB,4B 模型 Q4 量化后约 2.5GB,能整个放进显存跑。这是”能全显存运行”里体验最好的一个——具体参考第八节的完整选型表。
验证:
ollama run qwen3:4b
预期输出:进入交互模式,输入”你好”能看到它逐字生成回复。
5.4 Qwen3 默认会”先思考再回答”
第一次用 Qwen3 的人常被这个搞懵:问一句”1+1等于几”,它先输出一大段推理过程,最后才给答案。
这是它的「思考模式」,全系默认开启。三种关法:
| 方式 | 怎么写 | 说明 |
|---|---|---|
| 命令行(推荐) | ollama run qwen3:4b --think=false |
彻底关闭。另有 --hidethinking(保留思考但不显示)、--think=low/medium/high |
| API 调用 | 请求体加 "think": false |
写代码时用 |
| 桌面 App | 模型选择旁边的 Thinking 开关 | 新版 App 提供 |
~~末尾加 /no_think~~ |
—— | 网上流传但实测无效,别用 |
实测对比(qwen3:4b + 1050 Ti CUDA):开思考时约 10 字/秒,一道数学题要 80~130 秒,好处是有独立推理过程、会自检;关思考直接给答案。
使用建议:简单任务关掉,数学和复杂推理打开。但 4B 的推理深度有限,真要严肃推理得上 deepseek-r1:7b 或 qwen3:8b(代价是速度掉到 8~15 字/秒)。
六、第四步:跑通全链路
到这一步,两个组件都能单独工作了。现在把它们串起来,验证”文档 → 向量 → 存储 → 检索”这条链路。
# 1) 在 Qdrant 里建一个集合(注意 size 必须和 bge-m3 的 1024 维一致)
curl -X PUT http://服务器IP:6333/collections/test_kb -d '{
"vectors": { "size": 1024, "distance": "Cosine" }
}'
# 2) 把一段文字转成向量
curl http://localhost:11434/api/embed -d '{
"model": "bge-m3",
"input": ["向量数据库是用来做语义检索的"]
}'
# 3) 把向量写进 Qdrant(上一步返回的 embedding 数组填到 vector 字段)
curl -X PUT http://服务器IP:6333/collections/test_kb/points -d '{
"points": [{ "id": 1, "vector": [0.01, -0.02, ...], "payload": {"text": "向量数据库是用来做语义检索的"} }]
}'
# 4) 用另一句话检索,看能不能召回上面那条
curl -X POST http://服务器IP:6333/collections/test_kb/points/search -d '{
"vector": [/* 把"相似度检索怎么做的"转成向量填这里 */],
"limit": 3
}'
预期结果:第 4 步返回的 result 里,第一条就是第 3 步存进去的那句”向量数据库是用来做语义检索的”,score 接近 1.0。
注意第 1 步的 size 必须是 1024。写成 768 或者 1536 会直接报维度不匹配——这是最容易犯的错,因为不同嵌入模型的维度不一样(bge-m3 是 1024,有些是 768 或 1536)。
走到这里,你已经有一个可用的离线 RAG 基础环境了。
七、重头戏:CUDA 加速怎么开
前面几节都是”照着做就行”,这一节不一样——它是本次搭建中最费时间的部分,报错信息还很有迷惑性。如果你用的是老显卡(Pascal 及更早)且遇到相同现象,这里能直接帮你定位。
7.1 现象:一调用就崩
llama-server process has terminated: 0xc0000409
CUDA error: the provided PTX was compiled with an unsupported toolchain.
关键信息是第二句。翻译成人话:Ollama 内置的 CUDA 计算代码,是按新版本 CUDA 编译的;你的显卡驱动认不出这个新版本的中间码。
这里要解释一个概念——PTX:它是 CUDA 的”中间代码”,相当于程序编译到一半的产物。显卡驱动拿到 PTX 后,再针对具体显卡做一次编译(叫 JIT)。所以决定兼容性的不只是”驱动版本够不够新”,而是驱动能不能理解这份 PTX。
7.2 根因:老架构被新 CUDA 放弃了
GTX 1050 Ti 是 Pascal 架构(2016 年)。NVIDIA 在新版 CUDA 里逐步移除了对老架构的支持,所以会出现一个反直觉的现象:
驱动太新,反而跑不了。
具体到本次:本机驱动 560.94 太老,无法 JIT 编译 Ollama 内置 CUDA 产出的 PTX。但盲目装最新的驱动同样不行——最新的 617.14 安装器会直接拒绝 1050 Ti。
所以这里的关键认知是:CUDA 兼容性要同时看四个东西——显卡架构、驱动版本、CUDA Toolkit 版本、PTX 目标版本,四者要能对上。只看其中一个维度必然踩坑。
7.3 怎么查:驱动支持列表
不要靠猜,直接查 NVIDIA 官方的支持设备列表。查完之后是这样一个对照表:

| 驱动版本 | 是否支持 1050 Ti | 说明 |
|---|---|---|
| 617.14(2026-09) | ❌ | 安装器直接拒绝 |
| 591.44 / 591.74 | ❌ | 官方支持列表里已无 10 系 |
| 576.80(R575,2025-06-17) | ✅ | 最后一个官方支持 1050 Ti 的 Windows 驱动;对应 CUDA 12.8,PTX 8.7 满足 Ollama 的要求 |
| 581.57(R580,本机现状) | ⚠️ → ✅ | 官方已放弃 Pascal,但系统更新推送后实测装上了,CUDA v12 工作正常 |
给你的判断方法:查 NVIDIA 驱动页的「Supported Products」列表里,你的显卡型号还在不在。一旦某版本开始不列它了,就说明该版本之后都不支持了,要找最后一个还列的版本。
7.4 处理动作
Ollama 的安装目录里带了多个 CUDA 版本的库。要做两件事:
# 1) 把 cuda_v13 目录移出去(备份而不是删除)
# CUDA 13 彻底不支持 Pascal 架构,永久保持禁用
Move-Item "$env:LOCALAPPDATAProgramsOllamalibollamacuda_v13" `
"$env:USERPROFILEDownloadsollama-cuda-backup" -Recurse
# 2) 驱动装好之后,cuda_v12 保持原位即可(它本来就支持 Pascal)
验证成功的标志:看 Ollama 的日志(或 ollama serve 的输出),出现类似这一行——
library=CUDA compute=6.1 ... cuda_v12, GTX 1050 Ti
看到 library=CUDA 就说明 GPU 加速生效了。
效果:embedding 热启动处理 3 条约 255ms,换算下来约 12 条/秒。作为参照,纯 CPU 跑通常只有 1~3 条/秒——**提速 4~10 倍**,这就是 CUDA 的价值。
有一点必须清醒:CUDA 只提升速度,不提升显存容量上限。4GB 显存(实际可用约 3.3GB)仍然是模型体积的硬天花板。这是硬件决定的,驱动和软件都改不了。
八、模型选型:4GB 到底能跑什么
回到第 2.2 节算出来的结论——3.3GB 可用显存决定了一切。实测各类模型后,按体量分四档:

| 档位 | 体积 | 模型 | 速度 |
|---|---|---|---|
| A:全显存流畅 | ≤ 3.4G | qwen3:4b(2.5G)⭐、phi4-mini(2.5G)、llama3.2:3b(2.0G)、qwen2.5:3b(1.9G)、gemma3:4b(3.3G,可看图)、deepseek-r1:1.5b(1.1G)、qwen3:1.7b(1.4G) |
30–60 字/秒 |
| B:混合推理可用 | 4 ~ 6G | qwen3:8b(5.2G)⭐、glm4:9b(5.5G)、deepseek-r1:7b(4.7G)、qwen2.5-coder:7b(4.7G)、qwen2.5vl:7b(6.0G,看图)、yi:9b(5.0G) |
8–15 字/秒 |
| C:主要靠 CPU,只能尝鲜 | 7 ~ 9.3G | deepseek-r1:14b(9.0G)、qwen3:14b(9.3G)、phi4:14b(9.1G)、gemma3n:e4b(7.6G) |
3–6 字/秒 |
| D:不要装 | 10G+ | gpt-oss:20b、deepseek-r1:32b、qwen3:32b、gemma3:27b、qwen3-coder:30b |
CPU 拖不动 |
怎么用这张表:
- A 档:模型整个在显存里,速度流畅。做 embedding 和简单问答选这档,推荐
qwen3:4b(标 ⭐ 的是这一档里综合体验最好的) - B 档:超出显存,一部分要放内存里跑,速度掉到 A 档的 1/4。能接受延迟的话,回答质量明显更好
- C 档:主要靠 CPU,能出结果但要等——尝鲜可以,日常用不了
- D 档:直接放弃,别浪费磁盘
速度参照:”30–60 字/秒”大约是正常人阅读速度的 2~3 倍,体感是”逐字蹦出来”;”3–6 字/秒”则是一句话要等十几秒。
九、避坑清单
这些是搭建过程中实际踩到的零碎问题,单独列出来备查。每一条都附上”怎么判断自己遇到了”:
| # | 现象 | 原因与解法 |
|---|---|---|
| 1 | ./qdrant: /lib64/libc.so.6: version GLIBC_2.33 not found |
用了 gnu 版,它要求 glibc ≥ 2.33。换 musl 静态编译版。切忌升级系统 glibc——它是最底层的库,动它极易搞坏系统 |
| 2 | GitHub 上找不到 Qdrant 下载入口 | 预编译包在 Releases 页面,不在仓库首页 |
| 3 | http://IP:6333/dashboard 返回 404 |
面板挂在 /dashboard 子路径;也可能 config.yaml 里 service.web_ui 被设成了 false |
| 4 | 命令行传中文变成乱码 | Git Bash 会转码损坏。改用 UTF-8 文件落盘,再用 node / python 执行 |
| 5 | wmic 命令不存在 |
新系统已移除,查配置改用 PowerShell 的 Get-CimInstance |
| 6 | 桌面托盘 App 起不来,日志报 ollama server not ready after retries |
新版 ollama app.exe 在某些环境拉不起自己的 server。改用命令行直接执行 ollama.exe serve |
| 7 | schtasks 创建计划任务被拒 |
当前 shell 无管理员权限。改写成用户级注册表 Run 项实现开机自启 |
| 8 | Ollama 桌面端 Chat 列表里找不到 bge-m3 | 正常现象——它是嵌入模型不是对话模型,只走 API |
| 9 | ollama pull 之后模型又下到 C 盘了 |
OLLAMA_MODELS 没生效。重开命令行窗口,用 echo %OLLAMA_MODELS% 确认 |
| 10 | CUDA 突然失效了 | 检查 cuda_v13 目录有没有被移回来——它必须保持禁用(Pascal 不支持 CUDA 13) |
关于开机自启
如果 schtasks 被系统策略拒绝(常见于非管理员 shell),可以写用户级注册表实现自启:
HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionRun
OllamaServe = "%LOCALAPPDATA%ProgramsOllamaollama.exe" serve
用 reg add 命令或注册表编辑器都能加。
十、小结
整套环境的价值在于完全离线:从文本向量化到相似度检索再到对话生成,不经过任何外部服务。对 RAG 这类需要反复调试链路的场景,本地环境的好处是改一版立刻能验证,不受额度和网络影响。
最终跑出来的效果:embedding 约 12 条/秒,对话约 30~60 字/秒(qwen3:4b,关闭思考模式)。
三个最值得记的经验,按”能帮你省多少时间”排序:
- 动手前先查驱动支持列表。老架构显卡装 CUDA,最大的坑是”驱动版本对不对”。这次绕了一大圈,本质是没先确认 Pascal 在新版 CUDA 里已经被移除支持——查一下支持列表只要两分钟
- 4GB 显存能跑什么,是可以算出来的。可用显存 ÷ 每参数字节数,先算清楚再选模型,比装一堆模型挨个试快得多
- 遇到 GLIBC 版本报错,别升级系统 glibc。换静态编译版本(musl)更安全,动 glibc 可能把整个系统搞坏
下一步可以做的:把这套环境和业务打通——本地 bge-m3 生成向量,写入服务端 Qdrant(collection size=1024、Cosine 距离),再做检索结果的重排与引用溯源。
参考链接
- Qdrant Releases:https://github.com/qdrant/qdrant/releases
- Qdrant Web UI 文档:https://qdrant.tech/documentation/interfaces/web-ui/
- Ollama 官网:https://ollama.com(bge-m3 模型页 https://ollama.com/library/bge-m3)
- NVIDIA 驱动 576.80 详情页(支持列表含 GTX 1050 Ti):https://www.nvidia.com/en-us/drivers/details/248656/
- NVIDIA 驱动分支时间线:https://endoflife.date/nvidia

AI项目博客






