[{"data":1,"prerenderedAt":291},["ShallowReactive",2],{"blog-\u002Fblog\u002Fdgx-spark-self-hosted-llm":3},{"id":4,"title":5,"body":6,"date":279,"description":280,"extension":281,"meta":282,"navigation":283,"path":284,"seo":285,"stem":286,"tags":287,"__hash__":290},"blog\u002Fblog\u002Fdgx-spark-self-hosted-llm.md","我把部門唯一的 AI 主機搞掛了：自建 LLM 推理四個月實錄",{"type":7,"value":8,"toc":269},"minimark",[9,17,20,23,26,30,33,36,39,41,45,53,56,112,115,123,130,133,136,139,141,144,151,154,178,181,183,187,193,196,199,201,205,208,218,221,230,233,235,238,241,255,258],[10,11,12],"p",{},[13,14],"img",{"alt":15,"src":16},"深夜機房裡，記憶體量表爆表的 AI 主機，與走向電源鍵的人","\u002Fblog\u002Fimages\u002Fdgx-spark-self-hosted-llm-hero.png",[10,18,19],{},"五月的一個下午，我把部門唯一一台 AI 主機搞到完全沒反應。SSH 連不上，跑在上面的服務全部陪葬，最後是請 IT 走進機房、按下電源鍵，才把它救回來。",[10,21,22],{},"起因是我在啟動指令裡加了一個看起來很合理的 flag。",[24,25],"hr",{},[27,28,29],"h2",{"id":29},"這台機器是怎麼來的",[10,31,32],{},"三月中，部門進了一台 NVIDIA DGX Spark——128GB 統一記憶體的小型 AI 主機。我們拿它跑幾個內部服務：文字向量化的 embedding 模型、一個 31B 的語言模型、還有會議語音轉錄。我是兩個管理員的其中一個。",[10,34,35],{},"自建的理由很實際：內部文件不想丟給外部 API，批次任務跑雲端模型又太貴。一台機器放機房，內網打 API，聽起來很美好。",[10,37,38],{},"前兩個月也確實很美好。",[24,40],{},[27,42,44],{"id":43},"一個-flag一台屍體","一個 flag，一台屍體",[10,46,47,48,52],{},"五月中，我要在這台機器上評估一個新的本地推理引擎，模型檔 Q2 量化後 ",[49,50,51],"strong",{},"81GB","。",[10,54,55],{},"機器的記憶體當時長這樣：",[57,58,59,72],"table",{},[60,61,62],"thead",{},[63,64,65,69],"tr",{},[66,67,68],"th",{},"佔用",[66,70,71],{},"大小",[73,74,75,84,92,100],"tbody",{},[63,76,77,81],{},[78,79,80],"td",{},"31B 語言模型",[78,82,83],{},"~67GB",[63,85,86,89],{},[78,87,88],{},"Embedding 模型",[78,90,91],{},"~20GB",[63,93,94,97],{},[78,95,96],{},"語音轉錄",[78,98,99],{},"~4GB",[63,101,102,107],{},[78,103,104],{},[49,105,106],{},"合計",[78,108,109],{},[49,110,111],{},"~91GB \u002F 128GB",[10,113,114],{},"81GB 塞不進剩下的空間，所以我先停掉 67GB 的那隻騰位置。到這裡都照規矩來。",[10,116,117,118,122],{},"然後我在啟動指令加了 ",[119,120,121],"code",{},"--warm-weights","。這個 flag 的意思是：啟動時先把整份權重讀進記憶體「暖機」，第一次推理就不用等。聽起來很貼心，在獨立顯卡的機器上也確實是。",[10,124,125,126,129],{},"但這台機器是統一記憶體架構（UMA）：CPU 和 GPU 共用同一塊 ",[49,127,128],{},"128GB","。81GB 的權重一次灌進來，跟作業系統自己要用的記憶體搶同一塊實體空間，page fault 風暴直接把整個系統壓死。我手上沒有完整的驗屍報告，事後推測是連 SSH daemon 要的那一點記憶體都擠不出來——總之機器沒有變慢，它是直接失聯，連進去救的機會都沒有。",[10,131,132],{},"機房裡的機器，死得很安靜。",[10,134,135],{},"沒有畫面、沒有警報，你只會發現所有東西都 timeout。最後的解法很土：請 IT 走過去按電源鍵。",[10,137,138],{},"修正方式反而很不刺激：拿掉那個 flag，改用 lazy load。第一次推理慢一點，但機器不會死。那天我學到的一行字：在共用記憶體的機器上，任何「一次載入全部」的操作都是在賭命。",[24,140],{},[27,142,143],{"id":143},"同一天的第二個坑",[10,145,146,147,150],{},"機器活過來之後，我要把先前停掉的服務開回去，才發現第二件事：之前有服務是用 ",[119,148,149],{},"docker stop"," 停的，重開機後容器直接消失。它是 systemd 管的服務但沒設開機自啟，docker 層面看起來就是「不見了」。",[10,152,153],{},"那天之後，部門在 Slack 開了一個 channel 訂規矩，四條：",[155,156,157,165,168,171],"ol",{},[158,159,160,161,164],"li",{},"動手前先 ",[119,162,163],{},"free -h"," 看記憶體",[158,166,167],{},"要載入模型，先估算記憶體用量",[158,169,170],{},"要關別人的服務，先在 channel 喊一聲",[158,172,173,174,177],{},"操作服務一律走 ",[119,175,176],{},"systemctl","，不碰 docker 指令",[10,179,180],{},"四條全是翻車換來的。沒有一條是裝機那天想得到的。",[24,182],{},[27,184,186],{"id":185},"它又躺了一次這次不是我的錯","它又躺了一次，這次不是我的錯",[10,188,189,192],{},[119,190,191],{},"nvidia-smi"," 說找不到 GPU，三個服務全掛——這是本週某天早上這台機器給我的見面禮。前一天只做了一件事：例行的系統 kernel 升級。",[10,194,195],{},"查下去才發現：新 kernel 對應的 GPU driver 模組沒被裝上，因為套件庫索引太舊，安裝時默默 404。更麻煩的是裝完不能熱載入，driver 的 firmware 要在開機流程初始化，所以必須再重開一次機。中間那包 221MB 的 driver，從公司網路抓只有 77~256 kB\u002Fs，光下載就等了 15 分鐘。",[10,197,198],{},"服務掛了一個上午。這種故障不會寫在任何採購簡報裡。",[24,200],{},[27,202,204],{"id":203},"數字現實它到底能跑什麼","數字現實：它到底能跑什麼",[10,206,207],{},"四個月下來，最值錢的其實是幾個數字。",[10,209,210,211,214,215,52],{},"我實測那顆 81GB 的 Q2 模型，生成速度 ",[49,212,213],{},"13.75 token\u002Fs","。常駐的 31B 模型更慢：按規格換算大約 7 token\u002Fs，這不是我跑分跑出來的數字，但跟日常體感一致。用 7 token\u002Fs 算，一個 300 token 的回覆要等 ",[49,216,217],{},"40 秒上下",[10,219,220],{},"所以這台機器的能與不能，界線很清楚：",[222,223,224,227],"ul",{},[158,225,226],{},"❌ 任何要給使用者即時回覆的場景。40 秒的等待，什麼產品都撐不住",[158,228,229],{},"✅ 不趕時間的批次任務：離線跑評測、內部文件處理、embedding 向量化",[10,231,232],{},"我們後來的分工就是這樣：embedding 留在這台機器上跑，需要即時回覆的路徑走雲端 API。自建不是替代雲端，是跟雲端分工。這個結論值四個月。",[24,234],{},[27,236,237],{"id":237},"如果你的公司也在考慮這件事",[10,239,240],{},"買機器的錢是整件事裡最小的成本。真正的成本是這些問題有沒有人接：",[222,242,243,246,249,252],{},[158,244,245],{},"誰懂統一記憶體的行為？（不懂的話，一個 flag 就能讓它躺平）",[158,247,248],{},"記憶體預算誰管？多人共用時誰協調？",[158,250,251],{},"kernel 升級、driver 掛掉，誰半夜爬起來修？",[158,253,254],{},"你要跑的工作負載，它的推理速度真的撐得起嗎？",[10,256,257],{},"這四題沒有一題寫在規格表上，而我們是用四個月的翻車換來的答案。",[10,259,260,261,268],{},"如果你的公司正在評估自建 AI 主機或本地 LLM 推理，不管是為了資料不出門，還是想省 API 費用，都一樣：先別急著下單。把你的使用場景丟給我——",[262,263,267],"a",{"href":264,"rel":265},"https:\u002F\u002Fmattchang.dev",[266],"nofollow","mattchang.dev"," 上有我的 LINE，不用準備簡報，描述你想拿它做什麼就好。十分鐘，你就會知道該買、該租、還是該繼續用 API。",{"title":270,"searchDepth":271,"depth":271,"links":272},"",2,[273,274,275,276,277,278],{"id":29,"depth":271,"text":29},{"id":43,"depth":271,"text":44},{"id":143,"depth":271,"text":143},{"id":185,"depth":271,"text":186},{"id":203,"depth":271,"text":204},{"id":237,"depth":271,"text":237},"2026-07-13","一台 128GB 統一記憶體的 AI 主機進了部門。四個月裡我把它搞到 SSH 無回應、容器消失、GPU driver 全掛。這是自建 LLM 推理的真實成本清單。","md",{},true,"\u002Fblog\u002Fdgx-spark-self-hosted-llm",{"title":5,"description":280},"blog\u002Fdgx-spark-self-hosted-llm",[288,289],"ai-infra","llm","VjEP5pxzq2jyb7_-sTEDPiuOt-wFVsikM_ZM_WiASnE",1785903592272]