作者将本地模型部署到 ChatGPT 级别后发现,模型写 Python 容易,真正困难的是沙箱容器、文件上传、代码执行、网络隔离等基础设施层。
我花了一个周末试图把一个自定义 GPT 迁移到本地权重,模型部分大约一个小时就完成了。剩下整个周末都花在我从未想过的一个功能上:Code Interpreter。
我最初的假设是写 Python 是最难的部分,所以一个能写出不错 Python 的模型就够用了。这个假设在某个特定方面是错误的,值得点名,因为同样的错误出现在我读过的每一个"本地模型 vs ChatGPT"对比中。
写 Python 是简单的那一半。难的那一半是运行它。
当用户向一个自定义 GPT 上传 CSV 并要求绘图时,以下是 OpenAI 端发生的事情的形态:
生成的代码针对该文件执行
容器没有网络
它所做的任何事情都无法触及任何其他东西
这三项中的每一项都是某个人做出的决定然后运行的。没有一项是 prompt。无论权重在写 pandas 方面有多好,通过下载权重你都得不到其中任何一项。
所以当你离开自定义 GPT 时,这不是一项可以迁移的能力,也不是一项会消失的能力。它是一项需要你来托管的能力。这个区别对于规划来说非常关键,因为这三个类别行为完全不同:
我一直把三个都当作一个桶,贴上"我失去的东西"的标签,这使得整个决定看起来比实际更可怕,同时把"我加个沙箱就行了"归到周六下午的待办事项,这使得实际工作看起来比实际更容易。
任何人写的第一个东西是这样的:
exec(generated_code, {"__builtins__": {}})
这不是沙箱。剥离 builtins 对于任何能接触到类层次结构的东西来说都是一个减速带,而且生成的脚本不一定是恶意的才会伤害你。写出了意外的无限循环,或意外的 while True 往列表追加内容的模型,造成的损害和故意这么做的模型是一样的。
实际的需求,当我诚实写下来时:
文件系统隔离,因为用户上传的文件应该是代码唯一能看到的文件
无网络,因为一个决定执行 pip install 的模型就是一个刚刚把执行环境暴露给包注册表的模型
墙上时钟超时,会杀死进程,而不是客气地请求它停止
内存上限,与超时相同的原因
某种把图取出来的方式,这听起来很简单,直到容器被正确隔离,而现在你需要一条通道
所有这些都可以实现。gVisor、Firecracker、用 --network none 和 cgroup 限制锁定的 Docker 容器,或者如果你宁愿租用而不是运行,可以使用托管沙箱 API。没有任何一项是异域的。我一直在回想的是,在 ChatGPT 端,第 1 到 5 项是一个表单中的复选框。
我最终没有迁移那个使用 Code Interpreter 的助手,而是迁移了另外两个不用的。这听起来像是一种妥协,但实际上是一个有用的结果,因为它迫使问题按能力而不是按助手来问。
当原因是数据不能离开你的机器,或者当你希望模型在五年后仍能以相同方式运行,而不管届时定价页面上说什么时,这个迁移是值得的。当你的真实账单是工程时间时,这就不值得了。两个晚上重建检索的成本高于一年的 Plus,作为一个花了两个晚上的人,我这样说。
如果你想针对你自己的构建运行同样的审计而不是我的,Muse Glimmer vs GPTs 能力检查器正是做这个的:你勾选你的 GPT 实际使用了哪些功能,它会把它们分成迁移、重建和阻止三类,并显示每个的推理。它还会在告诉你任何鼓励的话之前问你有多少 VRAM,在被三篇独立的博文告知模型需要 17 GB 到 64 GB 不等之后,我很感激这一点。
如果我重新开始那个周末,我会在第一天完全跳过基准测试,只是列出我的助手使用了什么,把每个功能标记为代码或操作。我花周六大部分时间做的模型比较,事实证明不是决定任何事情的比较。