AWS ML ★ 85 6 min

Deploy decision models with llama.cpp on Amazon SageMaker AI

Advanced (300)Amazon SageMaker AITechnical How-to

🔗 https://aws.amazon.com/blogs/machine-learning/deploy-decision-models-with-llama-cpp-on-amazon-sagemaker-ai/

📌 用 llama.cpp 在 Amazon SageMaker AI 上部署決策模型:一份模型,兩種服務形態

TL;DR:同一份 GGUF 模型,既能跑 OpenAI 相容對話,也能直接吐出選項機率做路由決策。

路由請求、挑選 agent 動作、判定政策結果,這類應用要的往往不是一段生成文字,而是「在幾個固定選項裡,每個選項的機率是多少」。AWS 這篇文章示範了怎麼用同一個 llama.cpp 容器,同時服務這兩種截然不同的需求。

🤔 要解決的問題 生成式對話 API 回傳的是一段文字,應用端還要自己解析、猜測模型選了哪個選項。這篇文章延續 AWS 針對生成式 AI 推論打造的專用 Deep Learning Container(DLC)系列(先前已涵蓋 WhisperX、vLLM-Omni 兩篇),這次聚焦 llama.cpp:先用 AWS 官方 llama.cpp DLC 透過 SageMaker AI 的 InvokeEndpoint 提供 OpenAI 相容的 chat completions,再用 SemIf(前身叫 OpenJev)這個擴充,讓同一套 runtime 能在不解碼任何答案 token 的前提下,直接回傳每個候選選項的機率。

🧩 兩條部署路徑,同一份模型 標準路徑很直接:把模型打包成 model.tar.gz 放上 Amazon S3,直接引用官方發布的 DLC 映像檔。容器會自動找出 /opt/ml/model 底下第一個 .gguf 檔,把 POST /invocations 對應到 llama-server 的 /v1/chat/completions,並把 SM_LLAMA_CPP_* 環境變數轉換成 llama.cpp 的啟動參數。請求格式就是標準的 OpenAI Chat Completions schema(messages 陣列加上 max_tokens、stream 等生成參數),回應也是標準的 choices 陣列,從 choices[0].message.content 讀出生成文字。

但 llama-server 的 HTTP API 並不會把最後一個位置的 logits 與內部狀態操作暴露出來,而這正是 SemIf 需要的東西。因此結構化決策路徑改用 AWS CodeBuild 建置一個子映像檔,存進 Amazon ECR:子映像檔沿用原本 DLC 已編譯好的 CPU/CUDA 函式庫,只是把進入點換成相容 SageMaker 的 adapter。SemIf 的請求格式不是對話訊息,而是一組決策 schema:呼叫端自訂的 ID、一段非結構化的 state、一個問題,以及一組排好順序的允許選項。回應則會依同樣順序回傳 option_ids、probabilities 與原始 option_logits,外加 prompt、時間與固定模型版本的中繼資料。有了穩定的選項 ID,應用端就能直接套用門檻值、fallback 與政策檢查,不必再解析生成式文字。

💡 SemIf 不是唯一一種做法 文章指出,SemIf 屬於一整類「從非結構化 state 為應用自訂結果打分」的決策模型,同類實作還包括 TypeSafe 的 Jev(搭配 /v1/systemone API)、為相容 TypeSafe API 設計的模型伺服器 Kev,以及專為 agent workflow 設計、具校準輸出的 Strands Decider 2B。適合套用這套模式的場景包括:把案件路由到對的佇列、從已知集合中抽出單一值、判定事件優先等級、檢查政策結果,或是挑選 agent 的下一步動作。授權邏輯與確定性的商業規則仍應放在模型之外,模型吐出的機率也要先驗證,才能當作營運上的信心指標。值得注意的是,拿掉答案 token 的生成並不代表省掉推論,模型仍需完整處理 state、問題與選項描述,才能讓 SemIf 讀出最後的 logits。

📊 CPU 與 GPU 的實測差距 文章用同一組 231 筆公開的 JevBench 任務,分別序列送往一個 CPU endpoint 與一個 GPU endpoint 測試。GPU endpoint 在 p50 快了 4.9 倍,在 p95 快了 32.2 倍。範例用 SageMaker AI 的 instance pools 功能,依優先序列出相容的 GPU 機型(g6e、g6、g5、g4dn),實際測試中 SageMaker 選到 ml.g6e.xlarge,啟動紀錄顯示 llama.cpp 把全部 34 層模型都卸載到一張 NVIDIA L40S 上。另外,CPU 與 GPU 映像檔用的是不同的 llama.cpp 編譯版本,在 6 道較難的任務上給出不同答案,文章特別提醒,這該視為執行環境的差異,而不是「GPU 卸載讓模型品質變好」的證據。模型大小方面,較小的模型確實降低了中位延遲,但 2B 與 0.8B 候選模型的準確率只有 66.7% 與 58.4%,因此範例仍以 4B、Q4_K_M 量化版本作為預設的「品質優先」選擇。

⚠️ 使用時機與限制 文章建議:只有生成式對話需求時,直接用標準 SageMaker 文字生成路徑就好;只有當你需要 SemIf 這種直接存取 logits、state 的能力時,才值得多建一個子映像檔。CPU 適合背景、離線、低流量且能忍受數秒延遲的場景;GPU 適合互動式決策、長 prompt,或是對尾端延遲(tail latency)要求嚴格的場景。實務上建議把 state 與選項描述寫得精簡,把共用同一個 state 的多個決策合併成一次請求(可重複利用相同的 prompt 前綴),並透過增加 endpoint 執行個體數來處理併發;adapter 在內部 llama.cpp context 滿載時,會回傳可重試的 HTTP 503,而不是讓請求佇列無限堆積。文中也提醒,這些測試數據包含網路延遲,並非正式的服務等級承諾,實際上線前仍應針對自己的決策情境重新 benchmark。

🎯 實務啟示 如果你的系統本來就要做路由、分類、優先權判定這類「固定選項打分」的工作,卻一直在用生成式 API 加上後處理去解析答案,這篇教學提供了一個更直接的替代方案:同一份量化模型,用 SemIf 這類 adapter 直接拿機率,省掉解析生成文字的不確定性,也能用 option_logits 做更細緻的信心門檻設計。

🔗 來源

#AWS #SageMaker #llamacpp #DecisionModels #MachineLearning #MLOps #GPU #QuantizedModels #AIInfrastructure #AgentWorkflows

原始資料 AWS ML · 收集於 2026-10-12
來源原標題
Deploy decision models with llama.cpp on Amazon SageMaker AI
作者
Jyothirmai Kottu
原始標籤
Advanced (300) · Amazon SageMaker AI · Technical How-to
原始連結
https://aws.amazon.com/blogs/machine-learning/deploy-decision-models-with-llama-cpp-on-amazon-sagemaker-ai/

摘要原文

Applications that route requests, select agent actions, or assign policy outcomes often need scores over a fixed set of choices instead of free-form text. Deploying these decision models with llama.cpp on Amazon SageMaker AI gives you a managed path for serving quantized models on CPU or GPU infrastructure. This post continues a series on specialized AWS Deep Learning Containers (DLCs) for generative AI inference. Previous posts cover WhisperX , vLLM-Omni – Part 1 , and vLLM-Omni – Part 2 . In this post, you first use the AWS DLC for llama.cpp to serve OpenAI-compatible chat completions through SageMaker AI InvokeEndpoint . You then extend the same runtime with SemIf , formerly OpenJev, which returns probabilities over declared options without decoding an answer token. The accompanying code sample includes CPU and GPU deployment options. Figure 1 shows two deployment paths from the same packaged model. The text-generation path uses the AWS DLC for llama.cpp and returns generated responses through the OpenAI-compatible API. The structured-decision path builds a child image that replaces the default server with a SemIf adapter and returns probabilities for declared options. Figure 1: Run the AWS DLC for llama.cpp or the SemIf child image on CPU or GPU, depending on the API and latency requirements of your workload For the standard path, package the model as model.tar.gz in Amazon Simple Storage Service (Amazon S3) and reference the published DLC image directly. The container finds the first .gguf file under /opt/ml/model , maps POST /invocations to llama-server at /v1/chat/completions , and passes SM_LLAMA_CPP_* environment variables to llama.cpp arguments. The llama-server HTTP API doesn’t expose the final-position logits and state operations that SemIf uses. The structured-decision path therefore uses AWS CodeBuild to build a child image and store it in Amazon Elastic Container Registry (Amazon ECR) . The child image keeps the DLC’s compiled CPU or CUDA libraries while replacing its entry point with a SageMaker-compatible adapter. The AWS DLC for llama.cpp accepts the OpenAI Chat Completions schema. Send a messages array with role and content , plus generation controls such as max_tokens and stream : The response uses the OpenAI-compatible choices array. Read generated text from choices[0].message.content . SemIf uses a constrained decision schema instead of chat messages. The request contains a caller-defined ID, unstructured state, a question, and an ordered list of allowed options: The response returns option_ids , probabilities , and raw option_logits in the same order, along with prompt, timing, and pinned model metadata. With stable option IDs, your application can apply thresholds, fallbacks, and policy checks without parsing generated prose. SemIf belongs to a broader class of decision models that score application-defined outcomes from unstructured state. Other implementations include Jev , TypeSafe’s decision model and /v1/systemone API; Kev , a model server designed for TypeSafe API compatibility; and Strands Decider 2B , a purpose-built model for agent workflows with calibrated outputs. Use this pattern when your application defines the allowed choices at request time and needs a model to interpret unstructured context. Examples include routing a case to a queue, extracting one value from a known set, assigning an incident priority, checking a policy outcome, or selecting an agent action. Keep authorization and deterministic business rules outside the model, and validate model probabilities before treating them as operational confidence. Use the standard SageMaker AI text-generation path when you need OpenAI-compatible chat completions through InvokeEndpoint . The SageMaker AI image maps POST /invocations to the llama-server /v1/chat/completions endpoint. Build a child image only when your application needs behavior that this interface doesn’t provide, such as SemIf’s direct logits and state access. Removing answer-token generation doesn’t remove model inference. The model still processes the complete state, question, and option descriptions before SemIf reads the final logits. Keep prompts focused, and evaluate the selected model with labeled decisions from your application before production use. The following benchmark applies to the SemIf extension, not the text-generation endpoint. Model size, quantization, prompt length, runtime, and CPU thread count affect each decision. To quantify these trade-offs, we sent the same 231 public JevBench tasks serially to one CPU endpoint and one GPU endpoint. Compared with the CPU configuration, the GPU endpoint was 4.9 times faster at p50 and 32.2 times faster at p95. The sample uses the SageMaker AI instance pools feature to list compatible GPU instance types in priority order, so SageMaker can select an alternative when the first preference isn’t available. The pool ordered g6e , g6 , g5 , then g4dn . SageMaker selected ml.g6e.xlarge , and startup logs confirmed that llama.cpp offloaded all 34 model layers to an NVIDIA L40S. The CPU and GPU images used different llama.cpp builds and produced different predictions on six hard tasks. Treat the one-answer accuracy difference as runtime variation, not evidence that GPU offload improves model quality. Smaller models reduced median latency, but the 2B and 0.8B candidates achieved 66.7 percent and 58.4 percent accuracy. The sample therefore keeps the 4B Q4_K_M model as its quality-first default. These measurements include network latency and aren’t service guarantees. Benchmark the complete model and infrastructure configuration against your own decisions. Use CPU for background, offline, or low-throughput workloads that aren’t latency-sensitive and can tolerate seconds of response time. Use GPU for interactive decisions, long prompts, or workloads with tight tail-latency targets. Keep state and option descriptions concise, group decisions that share the same state into one request, and scale endpoint instances for concurrency. Shared-state scoring reuses the common prompt prefix, while the adapter returns retryable HTTP 503 responses instead of allowing an unbounded queue around its stateful llama.cpp context. The text-generation example uses the CPU DLC and a fixed CPU instance. The SemIf extension keeps CPU as the default for workloads that aren’t latency-sensitive and offers an optional CUDA image with ordered instance pools. Review SageMaker AI pricing before creating an endpoint. Use the following procedure to deploy the standard text-generation endpoint, then build the optional SemIf extension for structured decisions on CPU or GPU. Wait for the returned build ID to reach SUCCEEDED . The build records the source revisions and checksums in model-manifest.json and stops if the GGUF checksum differs from the validated value. Resolve a digest-pinned server-sagemaker-cpu-v1 image from the AWS DLC for llama.cpp documentation , then create the SageMaker AI model, endpoint configuration, and endpoint: Select a server-sagemaker-cpu-v1 or server-sagemaker-cuda-v1 image rather than the corresponding EC2 image. The SageMaker AI images implement the /ping and /invocations container contract and map invocation payloads to chat completions. This walkthrough supplies the GGUF model through the SageMaker AI model artifact in Amazon S3. As an alternative, you can configure SM_LLAMA_CPP_HF_REPO and SM_LLAMA_CPP_HF_FILE to download a GGUF file from Hugging Face when the endpoint has network egress. You don’t need a Dockerfile or an ECR repository for this path. Wait for the endpoint to enter InService , then send an OpenAI-compatible chat request: For GPU, build the CUDA child image instead: After the build succeeds, construct the immutable image URI: The deployment script rejects mutable image tags. The CPU configuration uses a fixed instance type: Wait for the returned endpoint name to enter InService . This path sets n_gpu_layers=0 .

由 claude-code/sonnet 自動生成