MENU

【歪门邪道】本地部署LLM的初尝试

May 1, 2026 • 瞎折腾

四月初谷歌发布了Gemma 4系列的开源模型。先前我对开源模型其实一直没什么太大兴趣,因为大部分都可以在OpenRouter上用到,价格远比自己买显卡便宜。但看到网上那么多人说Gemma 4这么好那么好,我寻思,这我得尝尝咸淡。于是陆续下单了两块AMD 7900XTX,尝试了在本地部署大模型。

Gemma 4

虽然已经过去了一个月,但我依旧记得当时清明假期看到Gemma 4发布的时候,大家对它的赞不绝口,同时模型的尺寸也从遥不可及变成了使使劲也能用。之前我对于开源模型一直没有太大的兴趣,主要是因为他们太大了。比如Qwen3.5 397B A17B,写代码很好用,但即便是4比特的量化,光是模型自己就要吃掉大约200GB的内存或者显存。MoE结构当然有优势,即便不能全部装进显卡也能取得比较快的计算速度,但就算这样,你仍然需要显存+内存的总量大于200GB,更别说还有用于上下文的kv cache。我这屋里所有设备的内存加起来还不到200GB,更别说插到一个主板上了,更何况现在内存价格那么贵,曾经600块钱的32GB内存我嫌贵,现在一条涨到3000块还买不到,我真的悔不当初。

但Gemma 4不一样。谷歌给出的口号是“Byte for byte, the most capable open models”,这个系列中最大的模型是31B,是个稠密模型,其次是26B A4B,这个是混合专家(MoE)模型。就算是我那个64GB内存+8GB显存的3070笔记本也能挑战一下,虽然只有惨兮兮的1 token/s,但确实让我领略到了这个模型的能力,它和我几年前尝试过的llama 2 70b确实不一样,进步很大(废话)。

于是想要更快更好地运行本地模型的想法在我心中不断酝酿着,更别说自己部署还能体验到各种uncensored模型,这种无(弱)对齐的体验简直是任何云服务都无法提供的。当然,最大的推手还是因为谷歌的AI Studio一直不提供付费的Gemma 4 31B访问,以至于我有钱没地方花;免费的一直有额度限制,同时谷歌也明确所有数据都会拿去训练。

AMD Yes!

在酝酿了一周后,我先下单了第一块7900XTX。为什么是AMD呢?因为隔壁英伟达买不起。比如说同样为24GB显存的RTX 5090D v2,阉割过不说,这一张卡竟然要两万!而没有阉割的5090,虽然有32GB显存,可是价格三万,我实在是家境贫寒。至于我这块蓝宝石的7900XTX白金版,24GB显存只要6000块,两块也只要1万2,这还要什么自行车?更别说Linux上面对AMD显卡的支持是开箱自用。虽然ROCm官方只支持一些商用Linux系统,但官方也提供了基于Ubuntu的docker容器,虽然我不喜欢Ubuntu,也不会装它作为我的主力系统,但有了docker,我可以无痛把显卡透穿给容器,完全不需要在主机上安装什么依赖啊闭源驱动什么的。尽管性能不比N卡,可是省心啊。

至于一周之后为什么下单了第二块显卡,那主要还是因为显存不够。一开始我以为只要把模型塞进显卡就好了,但其实这只是一部分,另一个大头是kv cache。

KV Cache

现代大语言模型普遍以注意力机制为基础,而大语言模型的输出又是一个字一个字往外蹦。因此当预测第N个字符的概率(logits)时,你需要将前面所有字符进行计算。为了防止计算量爆炸,人们在实现时普遍采用了一种缓存机制,即预测第N-1个字符的时候,就把注意力机制的K和V矩阵保存下来,因为这两个矩阵在不超过上下文长度的情况下是只增不减的。

这里严重简化了注意力机制的原理,请不要把这里说的当成学术入门。

简单来说注意力机制有三个矩阵:Q、K和V。他们都是由同一个输入矩阵X根据不同权重计算出来的。这里说是矩阵,其实可以理解为向量,例如X=(x1, x2, x3, x4, ..., xn),这里的xn可以理解为第N个token对应的embedding向量,为了计算过程能够发挥显卡的能力,我们不会挨个向量进行计算,而是将向量打包成矩阵,利用线性代数帮我们自动做for循环。

其中Q矩阵代表了当前的输入要查询什么样的信息,是一种需求。例如当前token是“他”,那么这个q向量就包含了对这个人称代词解引用的需求。而K矩阵则代表了每个token包含的信息的标签,例如之前一个token看着像人名,那么这个token生成的k向量就会标明自己是个人物。而V矩阵代表这个token实际包含的信息,比如文字里这个人叫“踏三山游五岳,恨天无把恨地无环,代管天津及周边各县真正大英雄王斯文”,那么这个v向量就会包含王斯文这个信息。注意力在计算的时候先要计算Q和K的乘法,这相当于用当前token的需求Q去筛选已知信息的标签K,得到的结果,某一行越大,说明这一行对应的信息就越有可能解答Q的需求。在得到这个筛选之后,再去和V乘,就相当于筛选出了V矩阵中真正有用或相关的信息。(线性代数,很神奇吧)

由于输入是确定的,模型的权重也是确定的,因此对于输入和模型预测出来的内容,K和V是完全不会变的,所以我们只需要每次将模型输出的token的k和v计算一下,然后追加到现有的k和v缓存中,就避免了每次都要重新运算前面内容的麻烦,但这种提速是用显存或者内存换来的。

对于Gemma 4 31B来说,它有10层全量注意力(4个kv head,每个512维)和50层SWA(sliding window attention,16个kv head,每个256维,长度1280)。因此该模型在最长上下文262144下的显存需求就是:

  • 全量注意力:262144(上下文)x 10(层)x 4(head)x 512(维) x 2(f16占用两字节)= 10GiB,那K和V加起来就是20GiB
  • SWA:1280(滑动窗口长度)x 50(层)x 16(head)x 256(维)x 2(f16占用两字节)= 500MiB,K和V加起来就是1000MiB,不到1GiB

因此整个模型光是KV Cache就要占用21GiB的显存,而我选择的Q5_K_M量化的模型本身才21.06GiB。这还没算用来存放中间计算结果的compute buffer(不到2GB)。所以这你就看出来了,想要上下文开的大,一块24GB显存的显卡根本不够用。所以我后来又买了一块。

双显卡配置

由于一块显卡显存不够吃,而kv cache放在系统内存又会让显卡受制于PCIE总线的速度,因此我决定下单第二块显卡。但问题在于怎么装。很显然,我的华硕GT502机箱并没有考虑让你装第二块显卡,我左思右想,欸,机箱前脸还有一片空间,不如就让它斜躺着吧:

2026-04-25T13:56:11.png

我还从淘宝上花了300块买了一根PCIE4.0x16的延长线,虽然那个插槽只支持PCIE4.0x4并且是通芯片组的,但令我惊讶的是,70cm的延长线,竟然能完美撑起来PCIE4的速度,国内的制造业有点东西的。当然,人家店里还有卖PCIE5.0延长线的,但是要500还是600来着,我寻思我这卡也就4.0的速度,没有这个必要。

当然,最大的问题还是电源。我这个主机是从亲戚那里继承过来的,不过这也是我亲手组装的就是了。当时组装的时候就没考虑双显卡的需求,因此电源用的是海韵的PX1000,额定功率1000瓦。可是蓝宝石的7900XTX,总板功率420瓦,这还没提短时间内的spike,要知道这电源可不是ATX3的电源。果不其然,在测试的时候灭了三次,其中prefill阶段(prompt processing)最为敏感,因为两张卡的利用率能接近100%并持续一段时间(这个时候是按照batch运行的)。至于文本生成阶段,因为每次计算出一个字都要两张卡交替运算,所以这个阶段的显卡利用率不是很高(大约50%)。

于是我决定痛定思痛,更换电源(没钱了)限制功率。

首先在主板里把CPU功率的短期功率限制为190瓦,长期功率限制在160瓦。我用的Fedora,安装LACT后启用超频,将功率限制到最低的272瓦,这个是长期功耗。为了防止短期功耗触发电源的保护,我将GPU核心频率限制到了2.6GHz,GPU电压偏移设置为-20mV。只要频率和电压限制住,他们就不会突然请求巨大功率导致电源触发保护。当然,代价就是性能打了折扣。英特尔13代14代的CPU主要是靠推功耗提供性能,所以一旦把功耗限制住了,对于计算密集的任务就会感觉到明显的变慢。至于GPU嘛,我没看过他们自由奔放的样子,没见过他们跑得快,自然也就不觉得他们跑得慢。

总之,现在无论怎么造,电源都不会熄火了。

部署方案

考虑到ROCm在fedora上并没有官方支持的包,而ROCm7的包要等到下一个大版本才行,我决定使用docker。早期由于llamacpp一直在更新,而官方的docker则是每天构建,想要用上最新的版本就得自己构建。不过最近对于gemma 4的支持稳定了不少,所以我就切换回官方的docker了。

至于为什么不选择vllm或者其他部署方案呢?归根结底还是显存不够,深究的话就是没钱。没钱是真难啊,我要是中了个2.2亿的彩票,我高低得整两块英伟达的H200尝尝咸淡。

一开始直接使用Docker命令进行部署,我整了个巨大的txt文件来保存对应的命令,但后来发现这样不方便切换模型,尤其是后面需要测试各种uncensored模型。一旦需要调整某个参数,就得对所有命令都进行调整。在测试了大约五六个模型之后,我有点受不了了。开始探索能够自动切换模型的方法。llama-server本身可以通过编写preset的方式切换模型,但他们切换的比较生硬:如果来了一个请求需要其他模型,他们会根据LRU算法杀掉最不常用的模型。但问题在于我的显存只够部署一个模型的,因此当我请求其他模型的时候,llama-server就会杀掉现在的模型,也不管当前请求有没有处理完,反正就硬杀。

在机缘巧合之下,我了解到了llama-swap,它能够根据请求自动切换模型,但一个好处是它能够等让请求排队,等当前的请求处理完了再切换模型。这真的太契合我的使用场景了。于是我的部署方法是在宿主机上运行llama-swap,然后让llama-swap调用docker来拉起容器。配置文件大概是这个样子:

logTimeFormat: "ansic"
captureBuffer: 256
startPort: 10001
globalTTL: 0
macros:
  # common start of docker run llama server
  # for debugging, use `llama.cpp:full-rocm` as image
  # for production, use just `docker pull ghcr.io/ggml-org/llama.cpp:full-rocm`
  "docker-server-rocm": >
    docker run --name ${MODEL_ID} --init --rm
      --device /dev/dri
      --device /dev/kfd
      --group-add=video
      --group-add=render
      --security-opt label=disable
      --security-opt seccomp=unconfined
      -p ${PORT}:8080
      -v /mnt/unenc-xfs/models:/models:z
      ghcr.io/ggml-org/llama.cpp:full-rocm
      --server
      --port 8080 --host 0.0.0.0
      --alias ${MODEL_ID}
 
  # cache and ctx-checkpoint settings for gemma 4
  # ctx-checkpoint will be huge since gemma 4 has a lot of standard attn layer
  # so we have to shrink the number of ckpts (default to 32) to reduce RAM usage, otherwise get OOM kill
  # on gemma 4 31b, each checkpoint takes 1GB of RAM
  "gemma4-ctx-ckpt": >
    --cache-ram 0
    --ctx-checkpoints 20
    --checkpoint-every-n-tokens 13107

apiKeys: []

models:
  "google-gemma-4-31b-q5km-text":
    name: "Google Gemma 4 32B Q5_K_M text"
    description: "256K context, no vision"
    cmd: |
      ${docker-server-rocm}
        ${gemma4-ctx-ckpt}
        --model /models/gemma-4/google-31B-it/google_gemma-4-31B-it-Q5_K_M.gguf
        --jinja
        --reasoning on
        -b 2048 -ub 256
        -ngl 99
        --main-gpu 0 --split-mode layer --tensor-split 30,31
        --ctx-size 262144
        --temp 1.0 --top-p 0.95 --top-k 64 --min-p 0.0 --repeat-penalty 1.0
        --mmap
        --no-kv-unified
        --flash-attn on
        --parallel 1
    cmdStop: docker stop ${MODEL_ID}
    proxy: http://127.0.0.1:${PORT}
    checkEndpoint: /health
    concurrencyLimit: 3
    timeouts:
      connect: 30
      keepalive: 30
      # pp may take a long time so we don't set a timeout here
      responseHeader: 0
      tlsHandshake: 10
      idleConn: 90


  "google-gemma-4-26b-a4b-q80-vision":
    name: "llmfan46 Gemma 4 28B A4B uncensored Q8_0 vision"
    description: "256K context, vision, image 560 tokens"
    cmd: |
      ${docker-server-rocm}
        ${gemma4-ctx-ckpt}
        --model  /models/gemma-4/google-26B-A4B-it/google_gemma-4-26B-A4B-it-Q8_0.gguf
        --mmproj /models/gemma-4/google-26B-A4B-it/mmproj-google_gemma-4-26B-A4B-it-bf16.gguf
        --jinja
        --reasoning on
        -b 2048 -ub 1024
        --image-min-tokens 560 --image-max-tokens 560
        -ngl 99
        --main-gpu 0 --split-mode layer --tensor-split 13,18
        --ctx-size 262144
        --temp 1.0 --top-p 0.95 --top-k 64 --min-p 0.0 --repeat-penalty 1.0
        --mmap
        --no-kv-unified
        --flash-attn on
        --parallel 1
    cmdStop: docker stop ${MODEL_ID}
    proxy: http://127.0.0.1:${PORT}
    checkEndpoint: /health
    concurrencyLimit: 3
    timeouts:
      connect: 30
      keepalive: 30
      responseHeader: 0
      tlsHandshake: 10
      idleConn: 90

通过定义macro的形式,能够让指令复用。之后我还测试了qwen3.5,还打算测试3.6,对于qwen来说用vulkan可能比用ROCm后端还好,因此只需要重新复制一份docker命令的开头,换个镜像就行了。

这里主要解释一下Gemma 4的两个版本和一些参数。

首先是docker命令:

    docker run --name ${MODEL_ID} --init --rm
      --device /dev/dri
      --device /dev/kfd
      --group-add=video
      --group-add=render
      --security-opt label=disable
      --security-opt seccomp=unconfined
      -p ${PORT}:8080
      -v /mnt/unenc-xfs/models:/models:z
      ghcr.io/ggml-org/llama.cpp:full-rocm
      --server
      --port 8080 --host 0.0.0.0
      --alias ${MODEL_ID}

这里用了一个不太常见的参数--init,这个参数的作用是用docker的init来代替默认的entrypoint。开启后容器内pid为1的进程就会被替换为/sbin/docker-init。通常这能确保孤儿进程被及时杀死,以及我们通过docker stop来关闭一个容器时,SIGTERM信号能被正确转发,尤其是full版本的镜像使用了一个tool.sh脚本来根据你传入的参数调用对应的二进制,这个脚本本身并没有对信号有什么特殊处理,所以这个参数对于能够正确及时地退出还是很重要的。

后面就是常见的传入设备,加入对应的组,调整安全设置之类的。因为fedora启用了selinux,所以挂载卷的时候跟了个:z的后缀。千万要注意必须是小写z,表示共享。如果写成大写Z,那么就会变成容器独占,可能会引发权限问题。

后面有一个专门针对prompt cache进行调整的宏:

  "gemma4-ctx-ckpt": >
    --cache-ram 0
    --ctx-checkpoints 20
    --checkpoint-every-n-tokens 13107

默认情况下checkpoint-every-n-tokens是8192,ctx-checkpoints是32。这对于qwen系列模型来说没什么问题,因为qwen的架构用了一些技巧来减少注意力对显存和内存的占用。对于Qwen3.5 27B模型来说,这样一个checkpoint大约是150MB不到,所以默认的32个检查点吃满也就才不到5GB的内存占用。但是Gemma 4 31B可是不一样,它一个检查点能够达到1GB的大小,如果按照默认的32个检查点来的话,光是这些检查点就要占用32GB的内存,还不算prompt cache(默认8GB)和其他一些组件占用的内存。这样一来就很容易触发OOM kill。

对于Gemma 4来说,由于内部采用了滑动窗口注意力机制,因此传统的prompt cache经常会遇到匹配失败,导致整个输入被重新计算。对于我这种单用户单请求的场景来说,关掉prompt cache,提高ctx checkpoints反而是体验更佳的做法。但受制于内存,我将数量缩减到了20个,并调大了生成检查点的间隔。

由于显存比较紧张,所以我部署了两个版本:

  • Gemma 4 26B A4B + Vision,由于MoE层数少,所以在最大上下文的情况下,我依旧能塞入Q8_0量化加上一个BF16的多模态投影模型。对于需要视觉的对话,我会选用这个模型。
  • Gemma 4 31B,稠密模型在编码等需要严谨思考的任务上表现比MoE模型好太多了,尽管速度比较慢。为了能够尽可能塞下位数更多的量化,我通过舍弃视觉模型将Q4_K_M改成了Q5_K_M,这种量化精度的提升在工具调用等方面带来了肉眼可见的改进。Q4量化的模型经常会出现工具调用错误的情况,而改成Q5之后,这种错误就显著减少了。我觉得Q6K量化可能更好,可惜我实在想不到办法它Q6_K模型全部塞进显存。除非牺牲上下文窗口。

这里面Gemma 4的视觉比较特殊,它使用了双向注意力机制,这意味着图片和当轮消息的文字必须要在同一个ubatch下处理,而调大ubatch尺寸会显著增加compute buffer对显存的占用。因此我把视觉留给了26B这个小一点的模型。此外,受制于显存,我的ubatch不能开特别大,所以就把图片的token数量限制到了560,剩下的内容留给文字。

双向注意力机制下的图片意味着图片里的不同部分能够相互看到,相互呼应。理论上来说这样有助于提升模型的原生视觉能力。隔壁Qwen3.5没有这个问题,因为他们使用的是casual attention,一个图片会变成一串token,随后这些token和文字一起可以被拆成小批次处理。这样做的好处是可缩放,但坏处就是图片前面的部分不能在注意力机制下引用后面的部分。

对于部署这两个模型,后面还有一些参数:

        --main-gpu 0 --split-mode layer --tensor-split 13,18
        --ctx-size 262144
        --temp 1.0 --top-p 0.95 --top-k 64 --min-p 0.0 --repeat-penalty 1.0
        --mmap
        --no-kv-unified
        --flash-attn on
        --parallel 1

第一行是告诉llama-server如何分隔模型。我显存有限,并且电源功率有限,因此选择了传统的layer分层,也就是一些层在一个显卡上,另一部分在另一块显卡上,这样就创造出了一种串行计算模式:前面的层在第一块显卡上完成计算,然后结算结果来到第二块显卡上继续计算。如果想要提升效率,可以考虑基于tensor拆分,这样两张卡可以同时计算,但对电源和显存的需求就显著上升了。

第二行是上下文,因为我有agentic coding的需求,大上下文是必须的。实际上256K我都嫌小,不过考虑到这个模型还没达到sonnet或者opus的能力,我并不会使用那么长的上下文。

第三行是采样参数,因为谷歌的模型一直比较独树一帜,包括他们家的Gemini 3系列也是这样,温度必须是1,topP和topK按照官方推荐的参数。至于minP和各种penalty,也要确保他们是关着的。llama-server的默认minP是0.05,需要调整成0才行。

第四行我开启了--mmap,因为我的显存能完全装下模型,并且考虑到我要频繁切换模型,因此这个参数能够提高加载速度。

第五行是关闭了统一kv cache。所谓统一kv cache,就是当你有多个slot的时候,这些slot可以共用一个kv cache。例如我想同时处理两个请求,但我想让两个请求都是256K上下文,那么通过开启统一kv cache,你就不需要一个512K的kv cache给两个请求平分,而是在两个请求的总量不超过256K上下文的情况下,共用这一个256K的kv cache。但由于llama server的实现是乐观实现,因此当所有请求的上下文总长超过256K的时候,所有请求都会同时失败。这一点在我进行测试时发现,如果opencode启动了多个sub agent同时干活,并且他们的上下文总和超出了256K,那么就会非常频繁地触发错误,导致所有agent都无法继续。因此我选择配合第七行,一次只处理一个请求,但这个请求独占256K上下文。

第六行是开启flash attention,这对于提升计算速度、减少显存占用有显著功效,不开不行。

尝试过的优化方案

我确实花了好一段时间尝试能不能缩减显存占用,这样我就可以塞进去量化精度更高的模型了。

节省缓存无外乎三种方法:

  • 去掉视觉模型
  • 减少上下文占用

    • 减少上下文
    • 使用kv cache量化
  • 调整ubatch size减少compute buffer占用

如你所见,对于31B模型我已经去掉了视觉模型。减小上下文长度是不可能的,本来256K就不算大,如果agent抓一些网页读一些代码,很快就不够用了。因此选择落在了最后两个方法上。

默认情况下llama server使用f16作为KV cache的数据类型,之前说过,一个参数占用2字节。理论上来讲你可以和主模型一样对其进行量化,例如设置-ctv q8_0 -ctk q8_0,但量化本身其实是一种无奈之举,通过牺牲模型的能力和精度换取更小的内存和显存占用。据传Gemma 4的模型本身对量化就比较敏感。模型本身从Q4提升到Q5之后我就感觉到了不同,所以我不是很想对KV Cache进行量化。况且llamacpp官方的docker构建对于非对称量化支持很差。

总之,这是我尝试的过程:首先是自己编译docker,要在cmake的时候添加一个额外的flag:-DGGML_CUDA_FA_ALL_QUANTS=ON,这是告诉编译器对flash attention开启更多支持。默认是支持kv同时量化为q8_0的,但如果我想保持ctk为f16,ctv为q8_0,那么官方的docker就会在CPU上计算,这个额外的flag能够修正这个问题。在我测试的时候还有内存泄漏的问题,尽管一个contributor嘴硬说不是内存泄露,但我觉得这就是嘴硬,解决方法是修改源代码:https://github.com/ggml-org/llama.cpp/issues/19979#issuecomment-4275846824

在完成这些之后重新编译容器便可以使用非对称量化。但测试时发现计算时需要从Q8_0反向量化,这样就导致计算时需要占用额外的显存来存放反量化后的V cache,这样一来虽然量化节省了5GB VRAM,实际却省不了这么多,并不能塞进Q6_K的模型,而V cache量化本身就已经让模型出现了工具调用出错的情况(例如调用sub agent时丢失字段),所以我认为整体得不偿失。最终放弃了方案。

作为最后的一点点挣扎,我尝试通过减小ubatch size来缩减compute buffer,配合上述量化看看能不能把Q6_K塞进去。最终我把ubatch size调到了32,但代价是PCIE通信显著增加,光是prompt processing的速度就跌到了100t/s,对于opencode来说,内置的agent提示词大约就10K token,也就是说哪怕你第一句只说个hi,也得等两分钟才能见到模型开始输出思考。这太慢了,根本用不了。最后只得放弃。

我还尝试了-nkvo,来把kv cache放到系统RAM,但这样一来显卡每次计算都要把数据从系统RAM发给显存,速度极慢,根本用不了一点。所以这个参数压根儿就没被列入可选方法。当然,如果你的设备是类似AMD新的那个AI系列的处理器,内置内存,可以尝试一下。对于一般的PC而言,系统RAM到显存要经过PCIE通信,这是巨大的瓶颈(主要是延迟),完全不值得尝试。

尝试过的use cases

之前我一直用OpenCode,因为我觉得这个软件在人类干预和Agent自动化之间达到了一个比较不错的平衡点,同时因为是开源的,所以我可以直接clone代码,遇到问题让agent辅助我探索代码寻找问题和解决方案。

前阵子OpenClaw比较火,但当时觉得这玩意儿很像厂商拿来骗token的,所以我直到完成部署本地llm之后才尝试。

太长不看:vibe coding只能得到一坨屎,无论是OpenClaw还是其竞品,都是一样的屎。

具体而言,OpenClaw的代码毫无设计可言,感觉就是AI吐了一地,我当时用的2026.04.15版本,dashboard连个配置文件都改不明白,有点招笑了。一开始为了防止感染赛博花柳病,所以我决定使用docker,但后来发现这东西的大部分场景还是针对物理机,尤其是mac进行优化的。容器化部署只是一个样子货,不好使。于是我掏出树莓派准备给它第二次机会,奈何它不中用呢。NodeJS编写的CLI在树莓派上太卡了,唯一说是有用的还是能够通过telegram访问一个agent,但对我来说用处也不大,我不是很喜欢让现在的LLM在我的设备上无监督free style。

后来我尝试了OpenClaw的其他竞品。

第一个是Hermes agent,不支持本地部署模型的原生视觉,其他的还行,这个属于巧克力味儿的屎。

第二个是NanoBot,用uv安装完成后,配置好本地llama server,跟我说缺少API KEY,配置了个假的也不行。连用都用不了。这是纯屎。

第三个是ZeroClaw,官方的安装脚本需要现场编译rust,很慢。同样配置好之后本地模型不支持原生视觉,而且配置和文档脱节严重,这是精心雕琢的屎。

果然一个好的软件还是需要良好的设计与代码组织。我觉得以当下的LLM来看,就算是opus或者mythos来了,在没有人为干预的情况下照样写不出来和人类一样优秀的项目。遂放弃尝试。

不过酒馆的体验倒是不错。虽然不如Gemini 2.5 pro和3.1 pro,但好处是本地模型不要钱。

后记

以上就是我尝试在本地部署LLM的经历了。目前我还在研究uncensored LLM,因为现在hugging face上有很多不同的作者都在做类似的事情,我需要找到哪个人的方法比较稳定。像是coder3101和llmfan46这些,他们主要用开源的heretic方案,还算易于验证的。闭源流派有HauHauCS和huihui.ai,他们的方法无从考证,因此只能通过实际测试来考查这些模型是否符合我的use case;更别说还有一堆新秀,比如wangzhang,试图革新uncensored model领域的评测方法,并在heretic的基础上进行了改进,虽然KL散度非常低,但实际测试却拉了一地。

我认为开放权重最优价值的就在于微调了。虽然OpenRouter上对Gemma 4模型的支持比较一般,有的量化打折,有的没开思考,但如果我只是想要原生模型的体验,那其实给OpenRouter或者其他hosting服务商充值就是了。而他们很难或者无法做到的,就是提供不同的uncensored或者微调的模型。我看到有人给qwen3.5用opus的语料进行微调,显著强化了它的思考能力;还有在R18语料上进行微调,能够提升NSFW角色扮演的表现;还有缝合怪(例如DavidAU),一套微调语料加上去对齐,角色扮演一把梭(coding就另当别论了)。在Reddit上还有讨论进行heretic权重消融后,通过微调来弥补消融对模型能力产生的负面影响的,只不过这种微调会比较昂贵,很少见hf上有这样做的。又因为我这个ROCm的环境,unsloth不好装,所以我也没发很好的尝试。总之我觉得在这方面真的有好多种探索不完的事情,非常有趣。

当然,这也意味着相关的文章可能要有一阵子才能发出来,因此下次更新大概率不会是uncensored模型相关的事情。但一如既往地,感觉大伙的阅读与捧场。我们下次更新再见。

-全文完-


知识共享许可协议
【歪门邪道】本地部署LLM的初尝试天空 Blond 采用 知识共享 署名 - 非商业性使用 - 相同方式共享 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 https://skyblond.info/about.html 处获得。

Archives QR Code
QR Code for this page
Tipping QR Code