Windows11部署Ollama本地大模型:完美对接WorkBuddy自定义接口

一台 2018 年的老机器(i7-8700 + 16GB + GTX 1060 6GB),从 CUDA 报错 到 显存 OOM 到 C 盘爆红,最后让 7B 代码模型正常跑起来,中间踩了十几个坑。这篇文章把每一条真实报错日志、根因、解法都记下来,附完整可用配置。

一句话结论先放这儿:GTX 1060 是 Pascal 架构(SM 6.1),而新版 llama.cpp 的 CUDA 编译架构列表里已经没有它了。你今天还能跑,靠的是旧后端兜底 —— 这意味着「能用」是暂时的,「升级即翻车」是常态。所以本文的核心策略是:跑通就冻结,别动它。
项目 配置 关键影响
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
这条不是报错,是警告,但它比报错更值得警惕。编译架构列表里已经没有 610(Pascal)了,现在能跑是因为它自动回退到了 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 工具研究游戏内存分析。

它一个纯文本模型,没有工具调用能力,连屏幕都看不到,怎么「使用」Cheat Engine?这句话在物理上就是假的。

为什么?模型不知道自己的能力边界。它回答「你会什么」时,是在预测「这类问题后面通常跟着什么文本」—— 而训练语料里,标准答案就是一份漂亮的能力清单。

正确姿势:别问它会不会,直接派活。

实测 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]]]   ← 深层没拆
这个错误比 3B 更隐蔽。打个比方:你让它「不用梯子把高处的东西拿下来」,它确实没用梯子,但只拿了手够得着的那一层。
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 &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;memory&gt;
#include &lt;variant&gt;
#include &lt;stack&gt;
 
// 递归结构:一个元素要么是 int,要么是"元素的列表"
struct Node;
using Ptr = std::shared_ptr&lt;Node&gt;;
struct Node {
    std::variant&lt;int, std::vector&lt;Ptr&gt;&gt; v;
};
 
static Ptr I(int x)              { return std::make_shared&lt;Node&gt;(Node{x}); }
static Ptr L(std::vector&lt;Ptr&gt; k) { return std::make_shared&lt;Node&gt;(Node{std::move(k)}); }
 
std::vector&lt;int&gt; flatten(const std::vector&lt;Ptr&gt;&amp; items) {
    std::vector&lt;int&gt; out;
    std::stack&lt;Ptr&gt; 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&lt;int&gt;(cur-&gt;v)) {
            out.push_back(std::get&lt;int&gt;(cur-&gt;v));
        } else {
            const auto&amp; kids = std::get&lt;std::vector&lt;Ptr&gt;&gt;(cur-&gt;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 };。

C# 里根本不存在「头文件」这个概念 —— 它靠 using 引命名空间。它居然用 C# 的 using 去回答一个 C++ 的「缺头文件」问题。

前四次是「做不对」(写代码能力不够),这次是「没听懂」。

而且它给的那套「检查引用、检查类型、构造测试数据、用调试工具、查文档」是万能模板 —— 放在任何语言、任何错误场景都「看起来成立」,对具体问题零作用。

典型特征:错误越具体,它越倾向于退回到泛泛而谈的建议。

四轮实测定级

轮次 任务 结果
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盘空间。
「约...GB」—— 它把模板占位符原样输出了,连数字都懒得填。

这是铁证:这份「日志」不是从真实操作记录里读出来的,而是照着「日志应该长什么样」凭空生成的文本。真实的记录会写「3.89 GB」,不会写「...」。

必须立刻做的事

关掉「工具调用」。WorkBuddy → 设置 → 模型 → 编辑 → 取消勾选「工具调用」→ 保存。

理由:工具调用依赖模型输出稳定格式的 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 的 Windows 自动更新存在已公开披露的漏洞(CVE-2026-42248):更新校验存在缺陷,下载下来的更新程序不做数字签名验证就直接执行。攻击者若能在网络链路上做中间人劫持,可让你在毫无察觉的情况下执行任意代码。

厂商给出的唯一缓解措施就是 关掉自动更新。

除了安全原因,还有两点: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"
模型本身永远不会自动升级。GGUF 权重就是硬盘上的静态文件,除非你主动 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
这套闭环的意义:以后模型给的每段代码,你都能在 10 秒内定性,不用再靠「读起来专不专业」去猜。
注意:保存时类型选「所有文件(*.*)」、编码选 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。硬件不同表现会有差异,但排查思路通用。

分享到:

用微信扫一扫,分享给朋友


发布日期:

所属分类: 编程语言 标签: