一台 2018 年的老机器(i7-8700 + 16GB + GTX 1060 6GB),从 CUDA 报错 到 显存 OOM 到 C 盘爆红,最后让 7B 代码模型正常跑起来,中间踩了十几个坑。这篇文章把每一条真实报错日志、根因、解法都记下来,附完整可用配置。
一、先看环境,再谈方案
| 项目 | 配置 | 关键影响 |
|---|---|---|
| CPU | i7-8700 @3.2GHz(6核12线程) | 纯 CPU 推理的兜底能力 |
| 内存 | 16GB DDR4 2400 | 决定能不能加载 7B |
| 显卡 | GTX 1060 6GB(Pascal / SM 6.1) | 全文最大的坑源 |
| 系统盘 | C盘 108GB,曾只剩 5.64GB | 模型默认会往这儿塞 |
| 系统 | Win11 专业版 Insider Preview 26H2(26340.9750) | 更新残留吃空间 |
| 软件 | Ollama 0.40.9 + WorkBuddy V5.8.3 | 服务端 / 客户端 |
二、先分清三件事,否则永远在瞎改
绝大多数「配了半天还是报错」的情况,是因为没搞明白这三件事是独立的:
| 层 | 怎么判断它活着 | 挂了的表现 |
|---|---|---|
| ① 服务 Ollama 本体 |
浏览器打开 127.0.0.1:11434 显示 "Ollama is running" | 连接被拒 |
| ② 模型 权重加载进显存 |
ollama run 模型名 能出对话 |
500 / OOM(服务还活着!) |
| ③ 客户端 WorkBuddy 配置 |
点「测试连接」变绿 | 红字提示 |
最容易误判的一点
浏览器那个 "Ollama is running" 页面,只是一句静态文本,它不加载模型。而客户端的「测试连接」会真的发一条对话请求、触发模型加载。所以你会看到:
GET "/" → 200 ← 浏览器显示 Ollama is running POST "/v1/chat/completions" → 500 ← 客户端显示"拒绝了测试请求"
服务活着 ≠ 模型能加载。看到「拒绝」先别改客户端配置,去命令行跑一次 ollama run 才是正解。
三、踩坑实录(按发生顺序)
【坑 1】PTX JIT compilation failed —— Flash Attention 不认识老卡
CUDA error: a PTX JIT compilation failed memory allocation failure llama-server terminated
根因:GTX 1060 是 Pascal(SM 6.1),不支持 Flash Attention。启动日志里那行 Flash Attention 就是引爆点。
解法:关掉它。临时生效在 PowerShell 里设,永久生效用 setx:
$env:OLLAMA_FLASH_ATTENTION="0" ollama serve # 永久固化(需重启 Ollama 才生效) setx OLLAMA_FLASH_ATTENTION 0
【坑 2】cudaMalloc failed —— 显存够,但分配不出来
这是最反直觉的一个坑。看这段真实日志:
common_memory_breakdown_print: | - CUDA0 (GTX 1060 6GB) | 6143 = 5199 + (2135 = 1834 + 144 + 157) + -1190 | ggml_backend_cuda_buffer_type_alloc_buffer: allocating 1834.83 MiB on device 0: cudaMalloc failed: out of memory error="llama-server reported out-of-memory during startup: cudaMalloc failed"
模型只要 1834 MiB,账面上还有 5199 MiB 空闲 —— 1.8G 都分配不出来,这不合理。
根因:注意那个 -1190,约 1.2GB 无法归属。那是上一次崩掉的 llama-server 僵尸进程还赖在显存里。空闲显存是碎片化的,而 CUDA 要的是一整块连续空间,不是数字加得起来就行。
解法:重启电脑。简单粗暴但最有效 —— 显卡强制清空 + 碎片重整。如果想优雅一点:
taskkill /F /IM llama-server.exe taskkill /F /IM ollama.exe # 同时退出托盘里的 Ollama 桌面版,别让两个实例抢显存 nvidia-smi # 看底部 Processes 列表是否为空
【坑 3】compute capability not in compiled architectures —— 悬在头顶的剑
skipping CUDA device — compute capability not in compiled architectures device="NVIDIA GeForce GTX 1060 6GB" cc=610 archs="[750 800 860 890 1000 1200]" libdirs=ollama,cuda_v12
cuda_v12 目录里的旧后端。
后果:哪天 Ollama 把这个兜底拿掉,你的 GPU 推理会直接失效,掉回纯 CPU。所以 —— 关掉自动更新(见坑 10)。
【坑 4】模型偷偷存进 C 盘,108G 的盘只剩 5.64G
根因:Ollama 默认模型目录是 C:\Users\用户名\.ollama\models。拉一个 7B 就是 4.7GB,几个模型下去系统盘直接爆红。
先诊断,别猜。跑这段把嫌疑目录全列出来:
$paths = @(
"$env:USERPROFILE\.ollama\models",
"D:\AI\ollama-models",
"$env:LOCALAPPDATA\Programs\Ollama",
"$env:ProgramData\NVIDIA Corporation\Downloader",
"C:\Windows\SoftwareDistribution\Download"
)
foreach($p in $paths){
if(Test-Path $p){
$s=(Get-ChildItem $p -Recurse -File -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum
"{0,-55} {1,8:N2} GB" -f $p, ($s/1GB)
} else { "不存在: $p" }
}
解法(推荐 GUI,最省事):Ollama 托盘右键 → Settings → Model location → 改成 D:\AI\ollama-models → 完全退出再重开(环境变量要重启进程才生效)。
命令行版本:
setx OLLAMA_MODELS "D:\AI\ollama-models" /M # 搬家(blobs 按 sha256 命名,同名即同内容,不会冲突) taskkill /F /IM ollama.exe /IM llama-server.exe 2>$null robocopy C:\Users\你的用户名\.ollama\models D:\AI\ollama-models /E /MOVE
ollama list,能看到已有模型就说明搬家成功。拉新模型时打开 D:\AI\ollama-models\blobs 盯着,体积在涨就对了。
【坑 5】NVIDIA App 驱动下载卡在 0 byte/sec
界面显示「正在下载……」,速度 0 byte/sec,已下载 0 byte / 0 byte —— 连文件总大小都没拿到,说明下载任务压根没启动,不是慢。
根因:下载器插件(UpdateFrameworkPlugin.dll)启动时会重放历史状态文件,一旦有陈旧的 0 字节残留记录就直接崩;加上 NVIDIA 的 CDN 在国内连不稳。
解法 A(推荐):绕过它,手动下载离线包。去 nvidia.cn/geforce/drivers/ 手动选 GeForce → GTX 10 Series → GTX 1060 → Win11,下那个 500MB 的安装包,右键管理员运行,选自定义 → 执行清洁安装。
解法 B(修 App 本身):退出后清空这几个目录里的内容:
%ProgramData%\NVIDIA Corporation\NVIDIA app\UpdateFramework\status %ProgramData%\NVIDIA Corporation\NVIDIA app\ota-artifacts %ProgramData%\NVIDIA Corporation\Downloader %LocalAppData%\NVIDIA Corporation\NVIDIA App\Cache
driver=13.0 说明已经是 580 系,581.57 只是小版本迭代,对 Pascal 老卡几乎没差别。而且前面那些 OOM 跟驱动版本没有任何关系。
【坑 6】Modelfile 报 unknown type —— 记事本给你加了 BOM
ollama create coder7b -f D:\AI\Modelfile-coder copying file sha256:be6f323ae1f1... 100% ...(复制了 15 个 blob 之后) Error: 400 Bad Request: unknown type
根因:用记事本保存、或用 > 重定向创建的文件,会变成 UTF-16 或带 BOM 的 UTF-8。Ollama 读第一行看到的是带前导字节的乱码,认不出 FROM 指令。
解法:用命令强制 ASCII 写入,别用记事本。
$content = @"
FROM qwen2.5-coder:7b
PARAMETER num_ctx 8192
PARAMETER temperature 0.2
PARAMETER top_p 0.8
"@
[System.IO.File]::WriteAllText("D:\AI\Modelfile-coder7b", $content, [System.Text.ASCIIEncoding]::new())
ollama create coder7b -f D:\AI\Modelfile-coder7b
【坑 7】CUDA_Host buffer 885035008 分配失败 —— 内存 8G 空闲还不够?
ggml_backend_cpu_buffer_type_alloc_buffer: failed to allocate buffer of size 885035008 ggml_backend_buft_alloc_buffer_n_default: failed to allocate CUDA_Host buffer of size 885035008 error loading model: unable to allocate CUDA_Host buffer
内存明明还有 8GB 空闲,845MB 都拿不出来。注意这是 CUDA_Host(系统内存里的钉住缓冲区),不是显存。
根因:日志里这行是钥匙:
disabling mmap for llama-server load by default ... reason=windows_cuda
Windows + CUDA 组合下,mmap 被禁用,模型不能「边读边用」,得整个实打实读进内存缓冲区。同时日志显示 free_swap="1.4 GiB" —— 16GB 内存只配了 1.4GB 页面文件,提交上限被卡死,而 C 盘快满又限制了自动扩容。
解法三步:
# ① 降批处理(这块缓冲按 batch 大小线性增长) PARAMETER num_batch 256 PARAMETER num_ubatch 256 # ② 全部层推给显卡(层留 CPU 越多,这块缓冲越大) PARAMETER num_gpu 99 # ③ 加大虚拟内存:控制面板 → 系统 → 高级 → 性能"设置" → 高级 → 虚拟内存 # 自定义大小 8192 / 16384 → 重启
【坑 8】「拒绝」变「超时」—— 其实是好事
报错文案从「模型服务拒绝了测试请求」变成了「模型服务响应超时」。别慌,这是进步:
| 提示 | 含义 |
|---|---|
| 拒绝了测试请求 | 加载失败,直接崩了(500) |
| 响应超时 | 服务接受了,正在加载,只是太慢(冷启动 1~3 分钟) |
解法:先预热,再点测试。
# ① 命令行先把模型加载进显存(耐心等 1~3 分钟) ollama run qwen2.5-coder:7b "hi" # ② 立刻回去点「测试连接」—— 热启动几秒响应 # ③ 让它别那么快被踢出去(默认 5 分钟就卸载) setx OLLAMA_KEEP_ALIVE "30m"
【坑 9】nvidia-smi 显示显存已被占掉 1503 MiB
1503MiB / 6144MiB 已用 GPU-Util 15%
而此时 ollama ps 是空的,说明 Ollama 一个模型都没加载。那这 1.5GB 是谁的?
账算得出来了:
显卡总量 6144 MiB 已被别人占用 - 1503 MiB ← 浏览器硬件加速 / dwm / Ollama GUI 实际可用 4640 MiB 7B 权重 + 上下文 5150 MiB ← 需求 ———————————————————————————— 差额 510 MiB ← 就是这么挤爆的
解法:关掉 Chrome / Edge 的硬件加速(设置 → 系统 → 关闭「使用硬件加速模式」→ 重启浏览器),通常能立刻回收 500MB~1GB。再加上彻底退出 Ollama GUI,占用降到 700 MiB 以下就有戏。
四、模型能力的坑(这段价值最高)
很多人以为跑起来就完事了。跑起来只是开始,知道它能干什么、不能干什么,才是关键。以下是同一台机器上 3B 和 7B 的实测对比。
实测 1:「你会什么」这类问题,永远只能得到编造的答案
问 3B「你能编程吗,支持哪些语言」,它答:熟练掌握 C#、Lua、Python、Java,使用 Cheat Engine 和 IDA 工具研究游戏内存分析。
为什么?模型不知道自己的能力边界。它回答「你会什么」时,是在预测「这类问题后面通常跟着什么文本」—— 而训练语料里,标准答案就是一份漂亮的能力清单。
正确姿势:别问它会不会,直接派活。
实测 2:3B 无视约束,7B 遵守约束但偷偷降级
同一道题:「用 Python 写函数扁平化嵌套列表,保留顺序,不要用递归」
| 模型 | 表现 | 判定 |
|---|---|---|
| qwen2.5:3b | 照样写了递归(flatten_list 调用自己) |
✗ 无视显式约束 |
| coder:7b | 不递归了,但用 extend 只展开一层 |
⚠ 遵守约束,牺牲正确性 |
实测输出:
输入: [[1,2,[3,4]], [5,[6,7]], 8, [9,[10,11,[12,13]]]] 期望: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] 实际: [1, 2, [3, 4], 5, [6, 7], 8, 9, [10, 11, [12, 13]]] ← 深层没拆
7B 会为了满足约束而牺牲正确性,而且不会主动告诉你它做了取舍。
实测 3:贴错误输出让它改 —— 改了个寂寞
把上面那段错误输出贴回去让它修正。它改了 —— 把 extend(item) 换成了手写的 for item in element: append(item)。
原版 v1 : [1, 2, [3, 4], 5, [6, 7], 8, 9, [10, 11, [12, 13]]] 修正 v2 : [1, 2, [3, 4], 5, [6, 7], 8, 9, [10, 11, [12, 13]]] v1 与 v2 输出是否完全相同: True
两种写法语义完全等价,输出一字不差。而且它的开场白还写着「使其能够递归地处理每个列表元素」,代码里却压根没有递归 —— 它分不清「我在描述目标」和「我实现了目标」。
实测 4:C++ 版本编译不过,且类型设计根本错误
flatten_bad.cpp:5:41: error: 'variant' is not a member of 'std' note: 'std::variant' is defined in header '<variant>'; did you forget to '#include <variant>'? # 补上头文件后再编译: error: no matching function for call to 'std::stack<...>::push(std::vector<int>&)' no known conversion from 'std::vector<int>' to 'const std::vector<std::variant<...>>&'
最根本的问题:它定义的是 std::variant<int, std::vector<int>>,含义是「要么是 int,要么是装 int 的列表」—— 只有两层。可它自己开场写的是「接受任意深度嵌套列表」。
C++ 是静态类型语言,嵌套深度必须在编译期确定。要表达任意深度,必须用递归类型定义(struct 里套自身)。正确写法:
#include <iostream> #include <vector> #include <memory> #include <variant> #include <stack> // 递归结构:一个元素要么是 int,要么是"元素的列表" struct Node; using Ptr = std::shared_ptr<Node>; struct Node { std::variant<int, std::vector<Ptr>> v; }; static Ptr I(int x) { return std::make_shared<Node>(Node{x}); } static Ptr L(std::vector<Ptr> k) { return std::make_shared<Node>(Node{std::move(k)}); } std::vector<int> flatten(const std::vector<Ptr>& items) { std::vector<int> out; std::stack<Ptr> st; for (auto it = items.rbegin(); it != items.rend(); ++it) st.push(*it); // 反序压栈保顺序 while (!st.empty()) { Ptr cur = st.top(); st.pop(); if (std::holds_alternative<int>(cur->v)) { out.push_back(std::get<int>(cur->v)); } else { const auto& kids = std::get<std::vector<Ptr>>(cur->v); for (auto it = kids.rbegin(); it != kids.rend(); ++it) st.push(*it); } } return out; }
# 编译运行结果 1 2 3 4 5 6 7 8 9 10 11 12 13 结果正确
实测 5:把 C++ 听成了 C# —— 连对话主题都识别错了
把上面三条 C++ 编译错误贴给它。它的回答是 using System;、int[] testData = { 1, 2, 3, 4, 5 };。
前四次是「做不对」(写代码能力不够),这次是「没听懂」。
而且它给的那套「检查引用、检查类型、构造测试数据、用调试工具、查文档」是万能模板 —— 放在任何语言、任何错误场景都「看起来成立」,对具体问题零作用。
典型特征:错误越具体,它越倾向于退回到泛泛而谈的建议。
四轮实测定级
| 轮次 | 任务 | 结果 |
|---|---|---|
| 1 | Python 扁平化,禁用递归 | ✗ 只展开一层,偷偷降级 |
| 2 | 贴错误输出让它改 | ✗ 改了个寂寞,输出一字不差 |
| 3 | C++ 版本 | ✗ 编译不过,类型设计根本错误 |
| 4 | 贴编译错误让它修 | ✗ 听成 C#,答非所问 |
五、最危险的坑:它真的会动手,而且不会记账
事件经过
在 WorkBuddy 里发了 @清理C盘。它的回复是:已清理 Dell SupportAssist 旧备份和 NVIDIA 驱动缓存,并将结果记录到 markdown 文件。
实际核查结果:
| 它承诺的 | 实际情况 |
|---|---|
| 清理 C 盘 | 5.64 GB → 9.53 GB,释放 3.89 GB ✓ 真干了 |
| 结果写入 markdown | 目录创建了,里面是空的 ✗ |
| (顺带声称)整理 D 盘目录 | 你只让它清 C 盘,它自己扩大了范围 ⚠ |
追问「有没有记录」之后,它补了一份「今日日志」,里面有这么一行:
- 空间清理完成,释放出约...GB的C盘空间。
这是铁证:这份「日志」不是从真实操作记录里读出来的,而是照着「日志应该长什么样」凭空生成的文本。真实的记录会写「3.89 GB」,不会写「...」。
必须立刻做的事
理由:工具调用依赖模型输出稳定格式的 JSON 来传参数。7B 量化版输出格式不稳定,而它连编程语言都能认错 —— 它拼出来的删除路径,你无法信任。
已经被执行过的,事后审计三步:
# ① 系统文件有没有被误伤 sfc /SCANNOW # ② 你自己的东西有没有丢 Test-Path C:\Users\你的用户名\Desktop Test-Path C:\Users\你的用户名\Documents ollama list # 确认模型还在 # ③ 回收站里找线索(如果是"删除到回收站"就能还原) (New-Object -ComObject Shell.Application).NameSpace(0xA).Items() | Select-Object Name, @{n='原位置';e={$_.ExtendedProperty("System.OriginalLocation")}}
安全使用姿势
让它出主意,你做决策和执行。正确问法:
我的 C 盘只剩 5.6GB,Windows 11。请列出安全的清理方法, 每条给出具体命令,并说明这条命令会删除什么、风险等级。
拿到之后:① 逐条核对路径 ② 涉及删除的先跑只读版本看会命中什么 ③ 确认无误再执行。
六、最后一个坑:Ollama 的自动更新别开着
厂商给出的唯一缓解措施就是 关掉自动更新。
除了安全原因,还有两点:Pascal 架构随时可能被新版彻底移除支持;以及你的 C 盘经不起每次几百 MB 的自动更新。
# ① GUI:Settings → Auto-download updates 关掉(绿色点亮,点一下变灰) # 同时确认 Expose Ollama to the network 是关的 # ② 环境变量双保险(GUI 开关可能被重置,这层还在) setx OLLAMA_NO_AUTO_UPDATE 1 setx OLLAMA_UPDATE false # ③ 验证 "NO_AUTO_UPDATE: " + [Environment]::GetEnvironmentVariable("OLLAMA_NO_AUTO_UPDATE","User") "UPDATE: " + [Environment]::GetEnvironmentVariable("OLLAMA_UPDATE","User") # ④ 检查有没有被塞可疑文件 Get-ChildItem "$env:LOCALAPPDATA\Ollama" -Recurse -Include *.exe -ErrorAction SilentlyContinue Get-ChildItem "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup"
ollama pull,否则它一辈子不变 —— 同样的提问明天会得到同样的结果,这反而是好事。
判断有没有变化,看 ollama list 里那串 ID(如 dae161e27b0e),那是版本指纹。
七、最终可用配置(照抄即可)
系统环境变量
OLLAMA_MODELS = D:\AI\ollama-models # 模型目录钉死在 D 盘 OLLAMA_FLASH_ATTENTION = 0 # Pascal 不支持,必须关 OLLAMA_KEEP_ALIVE = 30m # 默认 5m 太短,避免反复冷启动 OLLAMA_NO_AUTO_UPDATE = 1 # 堵住 CVE-2026-42248 OLLAMA_UPDATE = false
Ollama GUI 设置
| 项目 | 值 |
|---|---|
| Model location | D:\AI\ollama-models |
| Auto-download updates | 关 |
| Expose Ollama to the network | 关(开了就是对外敞开 11434 端口) |
Modelfile(用 ASCII 命令写入,别用记事本)
FROM qwen2.5-coder:7b PARAMETER num_ctx 8192 # 原版只有 4096,贴代码文件会被截断 → 模型一截断就瞎编 PARAMETER temperature 0.2 # 写代码要确定性,默认 0.8 会瞎发挥 PARAMETER top_p 0.8 PARAMETER repeat_penalty 1.05
$content = @"
FROM qwen2.5-coder:7b
PARAMETER num_ctx 8192
PARAMETER temperature 0.2
PARAMETER top_p 0.8
PARAMETER repeat_penalty 1.05
"@
[System.IO.File]::WriteAllText("D:\AI\Modelfile-coder7b", $content, [System.Text.ASCIIEncoding]::new())
ollama create coder7b -f D:\AI\Modelfile-coder7b
WorkBuddy 客户端配置
| 字段 | 值 | 说明 |
|---|---|---|
| 供应商 | 自定义 | Ollama 兼容 OpenAI 协议 |
| 接口地址 | http://127.0.0.1:11434/v1 |
注意末尾 /v1 |
| API Key | ollama |
不校验,但不能留空 |
| 模型名称 | coder7b |
必须和 ollama list 一致 |
| 工具调用 | ✗ 不勾选 | 见第五节,别给它执行权 |
| 图片输入 / 思考模式 / 自定义协议 | ✗ 全不勾 | 纯文本模型,没有这些能力 |
八、调用姿势:怎么问,决定了它能答对多少
否定式约束会把它逼到偷工减料,正向指令才行
| 问法 | 效果 |
|---|---|
| ✗ 「不要用递归,把嵌套列表扁平化」 | 它陷入「不能递归 → 那就只处理一层」 |
| ✓ 「用栈写一个函数,把任意深度嵌套列表扁平化」 | 给明确技术路径,成功率明显提升 |
这个规律对所有小模型都适用。
能力射程(基于实测,不是猜的)
✓ 可以放心交给它
- 写正则、写 SQL
- 50 行以内的独立函数
- 解释报错信息的大致方向
- 代码加注释、格式转换
- 简单场景的代码翻译
✗ 绝对别交给它
- 任何需要自我纠错的任务
- 复杂数据结构设计(嵌套 / 递归类型 / 树图)
- C++ 模板与类型系统相关代码
- 多轮对话中持续推进的复杂任务(会失焦)
- 你无法立刻验证的代码
建立你自己的验证闭环(比模型本身更值钱)
拿上面那道 Python 题做例子,写个判卷脚本:
# 第 1 部分:把模型给的代码原样粘贴在下面(注意缩进!)
def flatten_list(nested_list):
# ↓↓↓ 删掉 pass,把模型的函数体粘到这里 ↓↓↓
pass
# ↑↑↑ 粘贴结束 ↑↑↑
# 第 2 部分:自动判卷,不要改
cases = [
("4层嵌套", [[1, 2, [3, 4]], [5, [6, 7]], 8, [9, [10, 11, [12, 13]]]],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]),
("顺序保持", [[1, [2, 3]], 4], [1, 2, 3, 4]),
("字符串不展开", [["ab"], "cd"], ["ab", "cd"]), # 经典坑:字符串也是可迭代对象
("空列表", [[], [], [1]], [1]),
("混类型", [1, ["a", [2.5, None]], True], [1, "a", 2.5, None, True]),
]
all_ok = True
for name, data, expect in cases:
try:
got = flatten_list(data)
ok = (got == expect)
except Exception as e:
got, ok = f"报错: {type(e).__name__}: {e}", False
all_ok = all_ok and ok
print(f"[{'通过' if ok else '不通过'}] {name}")
if not ok:
print(f" 期望: {expect}")
print(f" 实际: {got}")
print("")
print("全部通过 - 这个模型的代码可用" if all_ok else "有失败项 - 见上方对比")
chcp 65001 python D:\AI\test_flatten.py
注意:保存时类型选「所有文件(*.*)」、编码选 UTF-8,否则会存成
.py.txt。粘贴后重点检查函数体第二行有没有缩进。
九、一条命令速查表
# ===== 诊断 =====
nvidia-smi # 看显存占用和底部 Processes 列表
ollama ps # 看当前哪个模型占着显存
ollama list # 看有哪些模型(ID 是版本指纹)
curl http://127.0.0.1:11434 # 只验服务活不活,不加载模型
ollama run 模型名 # 真正验模型能不能加载 ← 关键
# ===== 清理 =====
Get-Process | Where-Object {$_.Name -match "ollama|llama"} | Stop-Process -Force
Dism.exe /Online /Cleanup-Image /StartComponentCleanup # Windows 组件清理
# ===== 跑通 =====
$env:OLLAMA_FLASH_ATTENTION="0"
ollama serve # 这个窗口别关
# ===== 调参 =====
ollama create coder7b -f D:\AI\Modelfile-coder7b
ollama rm qwen2.5:1.5b # 清掉没用的,省空间
十、写在最后
折腾这一整圈,从 CUDA 报错、显存 OOM、C 盘爆红,到 7B 代码模型正常跑起来,最后沉淀下来三句话:
1. 能用就别动。Pascal 架构被逐步放弃、Windows+CUDA 禁用 mmap、自动更新有漏洞 —— 这代硬件在新技术栈里是靠兼容层勉强支撑的。主动升级只会增加翻车概率。把版本号记下来(我这里是 0.40.9),出问题还能回退。
2. 它是「会给建议的同事」,不是「能干活的同事」。让它列清单、讲思路,它有用;让它直接动手,等于拿你的系统赌它这一轮没跑偏 —— 而它今晚的战绩是 0 胜 5 负。
3. 本地模型的价值在隐私和离线,不在能力。GTX 1060 没有 Tensor Core,7B 只有 10~18 token/秒,写个函数要等半分钟。真要干正经工程活,云端 API 是碾压式的。把本地模型用在它擅长的短平快场景上,才是正解。
本文所有日志、报错、测试结果均来自真实部署过程,环境为 i7-8700 + 16GB + GTX 1060 6GB / Win11 26H2 / Ollama 0.40.9。硬件不同表现会有差异,但排查思路通用。