<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: GPUStack</title>
    <description>The latest articles on DEV Community by GPUStack (@gpustack).</description>
    <link>https://dev.to/gpustack</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1673709%2F6dfb7108-ed8e-4105-99f3-aaeb9ca11abd.png</url>
      <title>DEV Community: GPUStack</title>
      <link>https://dev.to/gpustack</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gpustack"/>
    <language>en</language>
    <item>
      <title>Introducing GPUStack v2.3: Optimizing LLM Inference with PD Disaggregation, Shared KV Cache, and Elastic Scheduling</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Thu, 29 Oct 2026 10:29:43 +0000</pubDate>
      <link>https://dev.to/gpustack/introducing-gpustack-v23-optimizing-llm-inference-with-pd-disaggregation-shared-kv-cache-and-3i65</link>
      <guid>https://dev.to/gpustack/introducing-gpustack-v23-optimizing-llm-inference-with-pd-disaggregation-shared-kv-cache-and-3i65</guid>
      <description>&lt;p&gt;&lt;strong&gt;The open-source edition of GPUStack v2.3.0 is now officially available!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Automated PD disaggregation orchestration, shared KV cache pools, vGPU partitioning, intelligent benchmarking, and scheduled autoscaling give model services more flexible resource configuration options. They also enable teams to deploy, validate performance, and continuously optimize services through a unified workflow.&lt;/p&gt;

&lt;p&gt;These capabilities address practical challenges that arise when models move into production: once Prefill and Decode are separated, how should instances work together? After a service scales out, how can it reuse existing caches? And how many resources should be provisioned for traffic peaks?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GPUStack v2.3 connects the management of resources, instances, caches, and traffic, allowing teams to focus more on model and business optimization while reducing repetitive work in multi-node deployment and day-to-day operations.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Layer of Systems Engineering Above the Inference Engine
&lt;/h2&gt;

&lt;p&gt;Inference engines such as vLLM and SGLang continue to improve model execution efficiency while adding capabilities such as distributed inference, PD disaggregation, and routing. These advances form an important foundation for the model services delivered by GPUStack.&lt;/p&gt;

&lt;p&gt;When enterprises adopt these capabilities, they often need to support multiple models, different inference backends, and heterogeneous GPUs at the same time. Beyond optimizing individual components, they must coordinate resource allocation, instance deployment, request routing, and configuration changes.&lt;/p&gt;

&lt;p&gt;PD disaggregation, for example, requires teams to organize Prefill and Decode instances and determine the right ratio between them, route requests through the corresponding processing stages, and maintain coordination among components as replica counts change. Each of these factors affects whether the service can continue to operate reliably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GPUStack incorporates this engineering work into the model service management workflow: users configure a service, and the platform organizes the underlying runtime components.&lt;/strong&gt; Version 2.3 further connects deployment, benchmarking, and runtime management, making advanced inference architectures easier to put into production and continuously tune.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated PD Disaggregation Orchestration: Configuring Resources Separately for Each Inference Stage
&lt;/h2&gt;

&lt;p&gt;Processing an LLM request primarily involves two stages: &lt;strong&gt;Prefill&lt;/strong&gt;, which processes the input context, and &lt;strong&gt;Decode&lt;/strong&gt;, which generates output tokens one at a time.&lt;/p&gt;

&lt;p&gt;These stages have different workload characteristics, and their resource requirements vary with input length, output length, and request volume. Deploying them separately makes it possible to tune resources and replica ratios independently for different production workloads.&lt;/p&gt;

&lt;p&gt;Version 2.3 introduces &lt;strong&gt;automated orchestration for PD-disaggregated deployments&lt;/strong&gt;, supporting the independent deployment, scheduling, and scaling of Prefill and Decode. Users configure the resources and replica counts for both roles, while GPUStack coordinates instance deployment, request routing, and collaboration as replica counts change.&lt;/p&gt;

&lt;p&gt;This allows teams to optimize input processing and output generation separately while reducing the effort required to maintain multi-instance configurations manually. After deployment, teams can also benchmark the service against actual hardware and request patterns to validate and adjust the P/D ratio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftven9711os8byqwnalzq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftven9711os8byqwnalzq.png" alt="Prefill and Decode resource and replica configuration" width="800" height="1436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Resources and replicas are configured separately for Prefill and Decode, while the platform organizes them into a single model service.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared KV Cache: Reducing Repeated Context Computation
&lt;/h2&gt;

&lt;p&gt;System prompts, knowledge base materials, and multi-turn conversation histories are often repeated across requests. Reprocessing the same content on every instance results in redundant computation.&lt;/p&gt;

&lt;p&gt;Version 2.3 introduces a &lt;strong&gt;shared KV cache pool&lt;/strong&gt; that, with compatible models and configurations, enables cache reuse across replicas and nodes. Multiple instances can reuse previously computed context and reduce repetitive Prefill work.&lt;/p&gt;

&lt;p&gt;GPUStack integrates shared caching solutions such as LMCache, Mooncake, and XSKY MeshFusion into model service management. Teams can configure caching at the service level and evaluate its effectiveness using cache hit rates and time to first token.&lt;/p&gt;

&lt;p&gt;Cache reuse must also be considered alongside request distribution and instance load. &lt;strong&gt;When a service scales from one instance to multiple instances, the results of prior context computation become a reusable resource.&lt;/strong&gt; Teams can assess the value of caching as they scale services and adjust routing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1ypc9hxon004f4gajv4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1ypc9hxon004f4gajv4.png" alt="Shared cache configuration for a model service" width="800" height="835"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Configuring a shared cache around a model service makes repeated context reusable across instances.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  vGPU Partitioning: Allocating Resources to Match Workloads
&lt;/h2&gt;

&lt;p&gt;Small models, development environments, and validation jobs do not necessarily need exclusive access to an entire physical GPU. Coarse-grained resource allocation can leave a portion of compute capacity idle for extended periods.&lt;/p&gt;

&lt;p&gt;Version 2.3 introduces &lt;strong&gt;vGPU partitioning&lt;/strong&gt;, supporting model and GPU instance deployment using both software-based and hardware-based resource partitioning. This allows different workloads to consume resources on demand. The available partitioning methods and isolation capabilities depend on the hardware and the corresponding solution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg53ew39j2lwdbh0clm94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg53ew39j2lwdbh0clm94.png" alt="Partitioning support for eight types of heterogeneous GPUs" width="799" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Partitioning support for eight types of heterogeneous GPUs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In Kubernetes environments, K8s workloads can directly request full, shared, or partitioned GPU resources provided by GPUStack Operator KDP.&lt;/p&gt;

&lt;p&gt;This extends the resource services introduced in v2.2: the same compute management system supports both model inference and development or experimentation. &lt;strong&gt;From full GPUs to partitioned resources, teams can allocate compute according to workload requirements and give smaller workloads an appropriately sized resource profile.&lt;/strong&gt; Instance monitoring then helps teams observe actual utilization and continue refining their configurations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fka0h62964b0kpjagwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fka0h62964b0kpjagwx.png" alt="Using partitioned resources for model deployment" width="800" height="1283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh81vs5tqtswsy6x7tw84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh81vs5tqtswsy6x7tw84.png" alt="Using partitioned resources for GPU instances" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Both model deployments and GPU instances can use partitioned resources, allowing teams to choose an allocation method suited to each workload.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intelligent Benchmarking and Scheduling: Aligning Service Capacity with Business Workloads
&lt;/h2&gt;

&lt;p&gt;Once a model is running, teams still need to understand how many requests the current configuration can handle and what kind of response experience it can deliver.&lt;/p&gt;

&lt;p&gt;A single throughput figure cannot adequately answer this question. As concurrency increases, both throughput and latency change. Differences in input and output lengths can also invalidate earlier test results.&lt;/p&gt;

&lt;p&gt;Version 2.3 introduces &lt;strong&gt;intelligent performance benchmarking&lt;/strong&gt;. A single test covers multiple concurrency levels and produces load curves and a recommended operating point. This helps teams explore the model's performance limits and determine service capacity based on the latency their applications can tolerate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbfcjd5ip7achf4t3ui45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbfcjd5ip7achf4t3ui45.png" alt="Performance results across multiple load levels" width="800" height="912"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fytu1w6ia61q85cci36h0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fytu1w6ia61q85cci36h0.png" alt="Recommended operating point" width="800" height="905"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Use throughput and latency across multiple load levels to select an operating point that meets application response-time requirements.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With capacity data in hand, teams can then plan traffic distribution and resource provisioning.&lt;/p&gt;

&lt;p&gt;Version 2.3 enhances gateway routing with load-balancing strategies such as session affinity and least requests, as well as &lt;strong&gt;model selection through a decision service&lt;/strong&gt;. The former manages request distribution across instances, while the latter selects an appropriate model for each request, enabling teams to configure traffic strategies based on service characteristics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F145qw7udok5mp19f3c7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F145qw7udok5mp19f3c7b.png" alt="Gateway routing configuration" width="800" height="1087"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4of7o558fsr2wcez0k2t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4of7o558fsr2wcez0k2t.png" alt="Decision-service model selection" width="800" height="1294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For predictable peaks and troughs, the platform also provides &lt;strong&gt;time-based autoscaling with tidal scheduling&lt;/strong&gt;. It adjusts model replica counts according to configured time windows, adding instances before recurring traffic peaks and reducing resource consumption during off-peak periods.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fufjbb5nw5ocdhdswqpjn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fufjbb5nw5ocdhdswqpjn.png" alt="Scheduled autoscaling configuration" width="800" height="877"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Adjust replica counts by time window to provision resources ahead of predictable traffic peaks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For example, a long-context knowledge base service can use shared caching to reuse repeated materials, run benchmarks to identify an operating point that meets response-time requirements, and then configure routing and a pre-peak scale-out plan. Every step revolves around the same service, and the configuration and observations from one step inform adjustments in the next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From “How many requests can the service handle?” to “How should requests be distributed, and when should resources be provisioned?”, performance data becomes the basis for day-to-day scheduling.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OTA and Deployment Management: Keeping Pace with Technology While Preserving a Recovery Path
&lt;/h2&gt;

&lt;p&gt;Models and inference backends evolve rapidly, and production services need a controlled way to adopt these changes.&lt;/p&gt;

&lt;p&gt;Version 2.3 introduces &lt;strong&gt;OTA updates for the model catalog and inference backends&lt;/strong&gt;. Without upgrading or restarting GPUStack, teams can update the model catalog, available inference backend versions, and the community backend marketplace online, gaining timely access to new deployment options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyw38i498fgcxft4ea0no.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyw38i498fgcxft4ea0no.png" alt="OTA update interface" width="799" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For individual services, teams can use &lt;strong&gt;YAML import and export&lt;/strong&gt; to save and reuse deployment configurations, apply validated configurations to subsequent deployments and environment migrations, and use &lt;strong&gt;deployment version history and rollback&lt;/strong&gt; to retain a record of configuration changes and restore a previous version when necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc3s3by9l103pafg1nu09.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc3s3by9l103pafg1nu09.png" alt="YAML import and export" width="800" height="701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqa4o5v7shcjch1yeha5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqa4o5v7shcjch1yeha5g.png" alt="Deployment version history and rollback" width="800" height="666"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reuse configurations through YAML, trace changes through version history, and restore a specific configuration version when necessary.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;OTA updates bring new capabilities to the platform promptly, while configuration reuse and version management allow teams to validate and adopt them at their own pace. &lt;strong&gt;From introducing new deployment options to reusing validated configurations and restoring previous versions, service updates now have a clearer operational path.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning Advanced Inference Capabilities into Model Services Built for Sustainable Operations
&lt;/h2&gt;

&lt;p&gt;The value of an inference optimization is ultimately realized in a production service: are resources allocated appropriately, is the deployment architecture maintainable, has capacity been validated, and are application requests handled as expected?&lt;/p&gt;

&lt;p&gt;GPUStack v2.3 connects PD disaggregation, shared caching, resource partitioning, and elastic scheduling through a unified service management workflow. Teams can choose an inference architecture based on application needs, validate its actual capacity, and continuously adjust resource and traffic configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is GPUStack's approach to systematic inference engineering: turning advanced inference capabilities into model services that can be delivered at scale and operated sustainably.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Try GPUStack v2.3 with a real-world workload and explore the deployment and operating model that best fits your needs. We also invite you to share your practical experience with the community.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
    </item>
    <item>
      <title>Can GPUStack Double GLM Inference Performance on 4 DGX Spark Nodes? From 24.3 to 51.3 tok/s</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Thu, 22 Oct 2026 07:28:12 +0000</pubDate>
      <link>https://dev.to/gpustack/can-gpustack-double-glm-inference-performance-on-4-dgx-spark-nodes-from-243-to-513-toks-26ll</link>
      <guid>https://dev.to/gpustack/can-gpustack-double-glm-inference-performance-on-4-dgx-spark-nodes-from-243-to-513-toks-26ll</guid>
      <description>&lt;p&gt;As GPU prices continue to rise, hardware that once seemed difficult to justify deserves another look. NVIDIA DGX Spark is one such system. Its price-to-performance positioning initially made us hesitant, but under today's procurement constraints, a small inference cluster built from several Spark systems is worth evaluating seriously.&lt;/p&gt;

&lt;p&gt;We connected four DGX Spark systems, managed them as one cluster with GPUStack, and served GLM-5.3-Flash-NVFP4 through vLLM. After two days of network tuning, MTP speculative-decoding work, and multi-node troubleshooting, we obtained the following results.&lt;/p&gt;

&lt;p&gt;Under our test conditions, &lt;strong&gt;single-stream decode throughput increased from 24.3 to 51.3 tok/s&lt;/strong&gt;, or &lt;strong&gt;2.11× the baseline&lt;/strong&gt;. &lt;strong&gt;Aggregate output throughput at four concurrent requests increased from 72.0 to 104.1 tok/s&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article focuses on three questions: what network tuning actually improved, why MTP initially failed to start, and which GPUStack multi-node deployment issues are worth avoiding in advance.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All numbers in this article come from this specific four-node cluster. The performance results apply to the model, configuration, and test cases described here. Interface names, paths, and parameters must be adapted to your own environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Test Environment: Four Spark Nodes with Cross-Node TP=4
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hardware and Network
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compute nodes&lt;/td&gt;
&lt;td&gt;4 × NVIDIA DGX Spark with the GB10 Grace Blackwell Superchip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unified memory&lt;/td&gt;
&lt;td&gt;128 GB per node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network adapter&lt;/td&gt;
&lt;td&gt;ConnectX-7; the logical interfaces used in this deployment are listed in the appendix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch&lt;/td&gt;
&lt;td&gt;MikroTik CRS804-4DDQ, four 200G access ports, RouterOS 7.19.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rail 1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;192.168.100.0/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rail 2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;192.168.101.0/24&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One detail about the “dual-rail” wording matters: according to our deployment records, &lt;strong&gt;the two logical interfaces on each node shared one 200G physical link; they were not two independent 200G links&lt;/strong&gt;. Each of the four nodes connected to one physical switch port.&lt;/p&gt;

&lt;p&gt;The topology also had an important limitation: the switch did not expose usable DCB/PFC/ECN configuration for this setup, so our tuning was concentrated on the NIC side. We therefore describe the configuration and results for this topology without claiming that it formed an end-to-end lossless network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Software and Model
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Orchestration&lt;/td&gt;
&lt;td&gt;GPUStack; Server on &lt;code&gt;node01&lt;/code&gt;, with four Workers registered in one cluster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference engine&lt;/td&gt;
&lt;td&gt;vLLM with the B12X attention backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eugr/spark-vllm-b12x:latest&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;GLM-5.3-Flash-NVFP4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quantization and cache&lt;/td&gt;
&lt;td&gt;NVFP4 weight quantization and FP8 KV cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallelism&lt;/td&gt;
&lt;td&gt;TP=4 across four nodes; PP=1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;GPUStack handled model configuration, Worker scheduling, and instance management. The lower-level inference and communication work centered on vLLM, MTP, and NCCL.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Fixing the Network First: Making Better Use of RoCE with NCCL
&lt;/h2&gt;

&lt;p&gt;Cross-node tensor parallelism makes inter-node communication unavoidable. We started with MTU consistency, NIC QoS, and NCCL interface selection.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Use a Consistent MTU
&lt;/h3&gt;

&lt;p&gt;We set the host MTU to 9000 and persisted it through netplan. On the switch, we used the platform-specific setting &lt;code&gt;mtu=9216&lt;/code&gt;; the recorded effective value was 9000.&lt;/p&gt;

&lt;p&gt;The important part is to &lt;strong&gt;verify the effective configuration and connectivity across the entire path&lt;/strong&gt;. Changing only the host configuration is not enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Configure NIC-Side QoS
&lt;/h3&gt;

&lt;p&gt;The following commands show one interface from our deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mlnx_qos &lt;span class="nt"&gt;-i&lt;/span&gt; enp1s0f0np0 &lt;span class="nt"&gt;--trust&lt;/span&gt; dscp
mlnx_qos &lt;span class="nt"&gt;-i&lt;/span&gt; enp1s0f0np0 &lt;span class="nt"&gt;-f&lt;/span&gt; 0,0,0,1,0,0,0,0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration used DSCP trust mode and enabled PFC for priority 3.&lt;/p&gt;

&lt;p&gt;One easy-to-miss detail caused confusion during early testing: &lt;strong&gt;&lt;code&gt;mlnx_qos -p&lt;/code&gt; configures priority mapping&lt;/strong&gt;, while &lt;strong&gt;&lt;code&gt;-f&lt;/code&gt; controls PFC&lt;/strong&gt;. Always read the configuration back after applying it and confirm that the effective state matches the intended one.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 Let NCCL Use Both Logical RDMA Interfaces
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NCCL_IB_HCA=rocep1s0f0,roceP2p1s0f0
NCCL_IB_TC=104
NCCL_IB_QPS_PER_CONNECTION=4
NCCL_IB_SPLIT_DATA_ON_QPS=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this setup, &lt;code&gt;NCCL_IB_TC=104&lt;/code&gt; corresponded to DSCP 26. Verify that it maps to the intended priority and queue under your NIC QoS configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Did the Network Tuning Improve?
&lt;/h3&gt;

&lt;p&gt;In our recorded four-node, 256 MB AllReduce test, bandwidth increased from &lt;strong&gt;4.0 GB/s&lt;/strong&gt; under TCP fallback to &lt;strong&gt;22.9 GB/s&lt;/strong&gt;, or approximately &lt;strong&gt;5.7×&lt;/strong&gt;. The single-rail comparison measured &lt;strong&gt;11.4 GB/s&lt;/strong&gt;, while the dual-rail configuration reached approximately &lt;strong&gt;2.0×&lt;/strong&gt; that result.&lt;/p&gt;

&lt;p&gt;These are bandwidth values from our NCCL test records. They should not be interpreted as physical port line rate.&lt;/p&gt;

&lt;p&gt;Time to first token (TTFT) also improved substantially in the long-input workload, as shown in Section 6. Network tuning did not double every metric, however. In our records, its direct effect on decode throughput was only about 2%–5%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network tuning removed the communication bottleneck&lt;/strong&gt;. The much larger improvement in single-stream decoding came after MTP was working.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Getting MTP Working: The Key to Doubling Single-Stream Decode Throughput
&lt;/h2&gt;

&lt;p&gt;GLM-5.3-Flash includes an MTP, or Multi-Token Prediction, module. We attempted to use it for speculative decoding, but this environment exposed two separate problems: weight loading and KV-cache layout compatibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 MTP Weights Were Loaded with the Wrong Quantization Format
&lt;/h3&gt;

&lt;p&gt;In this checkpoint, the MTP layer was layer 45, and its name did not explicitly contain &lt;code&gt;mtp&lt;/code&gt;. Its expert weights were actually BF16, but the quantization configuration's &lt;code&gt;ignore&lt;/code&gt; list did not exclude the layer. The draft side therefore allocated it as NVFP4, resulting in a 256/512 dimension mismatch.&lt;/p&gt;

&lt;p&gt;We fixed the issue by adding quantization-exemption rules to the model configuration on &lt;strong&gt;all four nodes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;First, back up the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /models/GLM-5.3-Flash-NVFP4
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; config.json config.json.bak-ignore45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then append the following four strings to both of these arrays:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;quantization_config.ignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text_config.quantization_config.ignore&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"model.language_model.layers.45"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"model.language_model.layers.45*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"model.layers.45"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"model.layers.45*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are &lt;strong&gt;entries to append&lt;/strong&gt;. Do not replace the existing &lt;code&gt;ignore&lt;/code&gt; arrays with this snippet. Layer 45 is specific to the checkpoint used in our test; verify the correct layer for other weight versions.&lt;/p&gt;

&lt;p&gt;After updating all four nodes, we deleted the corresponding model instance in GPUStack to trigger instance recreation and weight reloading. This interrupts the instance, so schedule it during an acceptable maintenance window.&lt;/p&gt;

&lt;p&gt;After the change, the MTP draft path loaded the layer as BF16 and the dimension mismatch disappeared. To roll back, restore the backup on every node and recreate the instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 The KV-Cache Layouts Were Incompatible
&lt;/h3&gt;

&lt;p&gt;Once the weights loaded, a second problem appeared between the FlashInfer backend used by the main model and the KV-cache layout used by the MTP draft path.&lt;/p&gt;

&lt;p&gt;The layout constraints conflicted. Some layouts could not split a 2,560-token management block into 256-token kernel blocks, while layouts that could be split were rejected by the parser. Initialization could not proceed.&lt;/p&gt;

&lt;p&gt;We initially built a locally patched image to relax the layout declaration. The configuration that ultimately worked was simpler: &lt;strong&gt;use B12X as the attention backend for both the main model and the draft path&lt;/strong&gt;. With this configuration, the management and kernel blocks no longer required the problematic split.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--attention-backend=B12X
--speculative-config={"method":"mtp","num_speculative_tokens":3,"moe_backend":"humming","attention_backend":"B12X"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then repeated the test with a base image that did not contain our local layout patch. The same configuration ran successfully and showed no meaningful performance difference in our records, so we removed the patch.&lt;/p&gt;

&lt;p&gt;The lesson was straightforward: &lt;strong&gt;when a backend compatibility issue appears, first check the support boundaries of the available backends before committing to a local patch&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Should the Speculative Depth Be 3 or 5?
&lt;/h3&gt;

&lt;p&gt;Once MTP was running, we still had to decide how many tokens to predict per step.&lt;/p&gt;

&lt;p&gt;The reference recipe used &lt;code&gt;num_speculative_tokens=5&lt;/code&gt;. In our four-node TP=4 environment, we compared depths 3 and 5. Each configuration ran three times, and the table reports the median:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test case&lt;/th&gt;
&lt;th&gt;Depth 3&lt;/th&gt;
&lt;th&gt;Depth 5&lt;/th&gt;
&lt;th&gt;Relative change at depth 5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single-stream, long-output decoding&lt;/td&gt;
&lt;td&gt;51.9 tok/s&lt;/td&gt;
&lt;td&gt;48.7 tok/s&lt;/td&gt;
&lt;td&gt;−6.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Four-request aggregate output&lt;/td&gt;
&lt;td&gt;110.0 tok/s&lt;/td&gt;
&lt;td&gt;96.7 tok/s&lt;/td&gt;
&lt;td&gt;−12.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The result was clear: &lt;strong&gt;depth 3 was faster in this test&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Our working hypothesis is that the additional computation from deeper speculation was not offset by an increase in accepted tokens. Confirming that explanation would require per-layer acceptance-rate and timing data; throughput alone is not enough to prove the cause.&lt;/p&gt;

&lt;p&gt;We therefore selected depth 3. A reference recipe provides a starting point, but workload-specific A/B testing should determine the final setting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance with MTP Enabled
&lt;/h3&gt;

&lt;p&gt;The following results come from the same benchmark suite. They compare the no-MTP baseline with the combined MTP × 3 and dual-rail configuration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test case&lt;/th&gt;
&lt;th&gt;No-MTP baseline&lt;/th&gt;
&lt;th&gt;MTP × 3 + dual rail&lt;/th&gt;
&lt;th&gt;Final/baseline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single-stream, short-output decoding&lt;/td&gt;
&lt;td&gt;24.4 tok/s&lt;/td&gt;
&lt;td&gt;50.0 tok/s&lt;/td&gt;
&lt;td&gt;2.05×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Single-stream, long-output decoding&lt;/td&gt;
&lt;td&gt;24.3 tok/s&lt;/td&gt;
&lt;td&gt;51.3 tok/s&lt;/td&gt;
&lt;td&gt;2.11×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Four-request aggregate output&lt;/td&gt;
&lt;td&gt;72.0 tok/s&lt;/td&gt;
&lt;td&gt;104.1 tok/s&lt;/td&gt;
&lt;td&gt;1.45×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-input decode throughput&lt;/td&gt;
&lt;td&gt;24.4 tok/s&lt;/td&gt;
&lt;td&gt;51.9 tok/s&lt;/td&gt;
&lt;td&gt;2.13×&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These numbers represent the benefit of the combined configuration. The entire gain should not be attributed to one parameter. The speculative-depth A/B test above came from a different run, which explains the small differences in absolute values.&lt;/p&gt;

&lt;p&gt;For functional regression, all 17 test prompts passed, including character-counting cases. This provides a basic functional check, but it is not equivalent to a full output-distribution equivalence study.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. A Silent Startup Hang: Gloo Selected the Loopback Address
&lt;/h2&gt;

&lt;p&gt;One failure was particularly difficult to diagnose from the dashboard. All four vLLM rank processes stopped during initialization, GPU utilization remained at 0%, and the logs contained no explicit error.&lt;/p&gt;

&lt;p&gt;We captured the call stacks with &lt;code&gt;py-spy&lt;/code&gt; and found the processes waiting in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gloo::transport::tcp::Pair::waitUntilConnected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relevant Worker processes were listening only on &lt;code&gt;127.0.0.1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Further investigation showed that &lt;code&gt;/etc/hosts&lt;/code&gt; inside the instance container mapped the hostname to a loopback address. When Gloo selected an address from the hostname, it attempted to use that loopback address for cross-node communication, preventing initialization from completing.&lt;/p&gt;

&lt;p&gt;The fix was to explicitly select the network interface for Gloo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GLOO_SOCKET_IFNAME=enp1s0f0np0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Setting only &lt;code&gt;NCCL_SOCKET_IFNAME&lt;/code&gt; did not resolve this failure. &lt;code&gt;GLOO_SOCKET_IFNAME&lt;/code&gt; had to be configured separately.&lt;/p&gt;

&lt;p&gt;We retained this variable in the final cluster configuration. For similar initialization hangs, check the &lt;strong&gt;call stacks&lt;/strong&gt;, &lt;strong&gt;listening addresses&lt;/strong&gt;, and &lt;strong&gt;hostname resolution inside the container&lt;/strong&gt; together.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Six Operational Lessons from a Multi-Node GPUStack Deployment
&lt;/h2&gt;

&lt;p&gt;GPUStack placed all four nodes under one configuration and instance-management workflow, which made it easier to repeat tests across different combinations. The following operational lessons were worth keeping.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This section describes observations from our deployment. API paths, log locations, and container behavior may vary by GPUStack version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5.1 Read the Configuration Back After an Update
&lt;/h3&gt;

&lt;p&gt;We used three main API operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET    /v2/models/&amp;lt;model_id&amp;gt;
PUT    /v2/models/&amp;lt;model_id&amp;gt;
DELETE /v2/model-instances/&amp;lt;instance_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They read model configuration, update it, and delete an instance to trigger recreation. The paths are illustrative; actual calls also require the appropriate authentication and request body.&lt;/p&gt;

&lt;p&gt;A useful habit is to &lt;strong&gt;run GET after PUT and verify that every critical field was saved as intended&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2 Verify the Effective Custom Image Separately
&lt;/h3&gt;

&lt;p&gt;In our deployment, we repeatedly observed &lt;code&gt;image_name&lt;/code&gt; becoming &lt;code&gt;None&lt;/code&gt; after a PUT, after which follower nodes used an unexpected image.&lt;/p&gt;

&lt;p&gt;We handled this by reading the configuration back, restoring the field when necessary, resubmitting it, and verifying the image actually running on every node. This is a troubleshooting record from our environment, not a claim that every GPUStack version behaves the same way.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3 Use Local Logs to Track Follower Progress
&lt;/h3&gt;

&lt;p&gt;In this deployment, the Web dashboard logs mainly reflected the leader instance. When a follower remained in “Preparing model files,” we inspected the log inside its Worker container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;gpustack-worker &lt;span class="nb"&gt;cat&lt;/span&gt; /var/lib/gpustack/log/serve/INSTANCE_ID.0.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm the actual path and filename suffix for your instance. Restarting the affected Worker recovered one failure in our tests, but doing so affects services on that Worker. Preserve the logs and assess the impact first.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.4 Scope Residual-Container Cleanup Precisely
&lt;/h3&gt;

&lt;p&gt;After deleting an instance, old containers occasionally remained on follower nodes and affected the next follower health check. A new instance could also begin creating containers almost immediately, making broad cleanup filters dangerous.&lt;/p&gt;

&lt;p&gt;We separated discovery from deletion: list candidate containers first, verify that they belong to the old instance, and only then delete the exact container ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List candidates first. The name filter only helps locate them;&lt;/span&gt;
&lt;span class="c"&gt;# verify the instance identity separately.&lt;/span&gt;
docker ps &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s1"&gt;'name=&amp;lt;OLD_INSTANCE_UNIQUE_SUFFIX&amp;gt;'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'table {{.ID}}\t{{.Names}}\t{{.Status}}'&lt;/span&gt;

&lt;span class="c"&gt;# After verification, replace CONTAINER_ID with the exact old container ID.&lt;/span&gt;
docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; CONTAINER_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.5 Verify the Container Runtime Requirements for RDMA
&lt;/h3&gt;

&lt;p&gt;The instance containers we inspected ran in privileged mode, used host networking, and had access to &lt;code&gt;/dev/infiniband&lt;/code&gt;, providing the runtime conditions needed for RoCE inside the container.&lt;/p&gt;

&lt;p&gt;Those conditions alone do not prove that RDMA communication is working. We still used the container configuration, NCCL logs, and communication benchmarks together to verify the effective transport.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.6 Use a Custom Image When the Backend Requires It
&lt;/h3&gt;

&lt;p&gt;Under GPUStack's inference-backend configuration, we specified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image: eugr/spark-vllm-b12x:latest
Entry command: vllm serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This provided the required B12X-enabled vLLM environment. We then managed the test combinations through model parameters and environment variables. As with every other configuration change, verify the image and launch arguments on the running instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Final Configuration and Results
&lt;/h2&gt;

&lt;p&gt;We settled on the following configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Four nodes with TP=4 and PP=1.&lt;/li&gt;
&lt;li&gt;B12X as the attention backend for both the main model and MTP draft path.&lt;/li&gt;
&lt;li&gt;MTP speculative depth 3.&lt;/li&gt;
&lt;li&gt;Two logical RDMA interfaces for NCCL and an explicitly selected Gloo interface.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gpu-memory-utilization=0.85&lt;/code&gt; and &lt;code&gt;max-model-len=500000&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We did not retain &lt;code&gt;kv_cache_memory_bytes=8G&lt;/code&gt; from the reference configuration, nor did we raise &lt;code&gt;gpu-memory-utilization&lt;/code&gt; to 0.87. We preferred additional operating headroom over maximizing allocated memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance Results
&lt;/h3&gt;

&lt;p&gt;Application-level results are the median of three &lt;code&gt;bench.py&lt;/code&gt; runs. NCCL bandwidth is listed separately so that communication bandwidth is not confused with model output throughput.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Application metric&lt;/th&gt;
&lt;th&gt;Baseline&lt;/th&gt;
&lt;th&gt;Final result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single-stream, long-output decoding&lt;/td&gt;
&lt;td&gt;24.3 tok/s&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;51.3 tok/s&lt;/strong&gt;, &lt;strong&gt;2.11×&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Four-request aggregate output&lt;/td&gt;
&lt;td&gt;72.0 tok/s&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;104.1 tok/s&lt;/strong&gt;, &lt;strong&gt;1.45×&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TTFT in the long-input case&lt;/td&gt;
&lt;td&gt;1.73 s&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0.12 s&lt;/strong&gt;, approximately &lt;strong&gt;93% lower&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The TTFT result applies to this particular test case. Because the article does not fully specify input length, cache-hit state, and warm-up conditions, it should not be extrapolated to arbitrary long-input requests or attributed to one network parameter alone.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Communication metric&lt;/th&gt;
&lt;th&gt;Baseline&lt;/th&gt;
&lt;th&gt;After tuning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Recorded NCCL AllReduce bandwidth&lt;/td&gt;
&lt;td&gt;4.0 GB/s&lt;/td&gt;
&lt;td&gt;Approximately 19–23 GB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We also raised &lt;code&gt;max-model-len&lt;/code&gt; from the previously recorded 32K tokens to &lt;strong&gt;500,000 tokens&lt;/strong&gt;. This is a configuration limit, not evidence that we completed end-to-end validation of one 500K-token request or four concurrent 500K-token requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restart Stability
&lt;/h3&gt;

&lt;p&gt;Three scripted restart tests all succeeded on the first attempt. Time to readiness was approximately &lt;strong&gt;12.5–13.5 minutes&lt;/strong&gt;, including about five minutes for weight loading, seven minutes for B12X kernel tuning and related initialization, and the remaining time for other startup steps.&lt;/p&gt;

&lt;p&gt;These three runs were sufficient for our configuration sign-off, but longer-duration stability still requires continued observation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Takeaways: Give Every Important Choice a Comparison
&lt;/h2&gt;

&lt;p&gt;Two lessons stood out after the two-day tuning effort.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;select a backend combination that is actually compatible&lt;/strong&gt;. B12X resolved the MTP layout issue in our environment and allowed us to remove the local patch used during troubleshooting.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;use controlled comparisons to choose parameters&lt;/strong&gt;. Single rail versus dual rail, speculative depth 3 versus 5, and no MTP versus the final combined configuration answered different questions. Testing them separately made it easier to identify where each gain came from.&lt;/p&gt;

&lt;p&gt;GPUStack gave us one multi-node management plane for the experiment, while the final performance came from the network, inference backend, and model configuration working together. If you are experimenting with your own Spark cluster, we hope this record provides a useful troubleshooting path.&lt;/p&gt;

&lt;p&gt;Share your hardware configuration, benchmark method, or GPUStack multi-node deployment experience in the comments.&lt;/p&gt;




&lt;h2&gt;
  
  
  Appendix: Deployment Configuration
&lt;/h2&gt;

&lt;p&gt;The values below reproduce our environment. Verify your GPUStack and model versions, checkpoint layout, interface names, and available memory before using them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Model Configuration
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Value used in this test&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model source&lt;/td&gt;
&lt;td&gt;&lt;code&gt;local_path&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local path&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/models/GLM-5.3-Flash-NVFP4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Distributed inference&lt;/td&gt;
&lt;td&gt;Cross-Worker distributed inference enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend version label&lt;/td&gt;
&lt;td&gt;vLLM (&lt;code&gt;0.31.0-spark-custom&lt;/code&gt;, preserved from the deployment record)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image&lt;/td&gt;
&lt;td&gt;&lt;code&gt;eugr/spark-vllm-b12x:latest&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replicas&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;backend_parameters&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Each line below is one backend parameter. Pass the JSON value for &lt;code&gt;--speculative-config&lt;/code&gt; as one complete argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--distributed-executor-backend=mp
--tensor-parallel-size=4
--trust-remote-code
--max-model-len=500000
--gpu-memory-utilization=0.85
--max-num-seqs=4
--max-num-batched-tokens=8192
--kv-cache-dtype=fp8
--block-size=256
--mamba-cache-mode=align
--no-enable-flashinfer-autotune
--enable-auto-tool-choice
--tool-call-parser=glm47
--reasoning-parser=glm47
--attention-backend=B12X
--speculative-config={"method":"mtp","num_speculative_tokens":3,"moe_backend":"humming","attention_backend":"B12X"}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment Variables
&lt;/h3&gt;

&lt;p&gt;Enter these as separate key-value pairs in GPUStack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VLLM_USE_AOT_COMPILE=1
VLLM_USE_MEGA_AOT_ARTIFACT=1
VLLM_USE_V2_MODEL_RUNNER=1
CUTE_DSL_ARCH=sm_121a
VLLM_MEMORY_PROFILER_ESTIMATE_CUDAGRAPHS=0
VLLM_SSM_CONV_STATE_LAYOUT=DS
NCCL_IB_HCA=rocep1s0f0,roceP2p1s0f0
NCCL_IB_TC=104
NCCL_IB_QPS_PER_CONNECTION=4
NCCL_IB_SPLIT_DATA_ON_QPS=1
NCCL_SOCKET_IFNAME=enp1s0f0np0
GLOO_SOCKET_IFNAME=enp1s0f0np0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We additionally enabled these variables during troubleshooting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=INIT,NET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pre-Launch Checklist
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Apply the layer 45 quantization exemptions required by this checkpoint on all four nodes, and retain a backup of the original configuration.&lt;/li&gt;
&lt;li&gt;Read back and verify the effective MTU, DSCP trust, priority mapping, and NIC-side PFC settings. Confirm that persistent configuration matches runtime state.&lt;/li&gt;
&lt;li&gt;Confirm that the RDMA and Gloo interface names match the actual devices on every node.&lt;/li&gt;
&lt;li&gt;This configuration does not pin &lt;code&gt;NCCL_IB_GID_INDEX&lt;/code&gt;; NCCL selects it automatically. Check the selected value in the startup logs.&lt;/li&gt;
&lt;li&gt;After recreating the instance, verify the effective image and parameters on every node, then run communication, health, and real-inference checks.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.nvidia.com/en-us/products/workstations/dgx-spark/" rel="noopener noreferrer"&gt;NVIDIA DGX Spark specifications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.nvidia.com/dgx/dgx-spark/spark-clustering.html" rel="noopener noreferrer"&gt;NVIDIA DGX Spark ConnectX-7 networking guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.gpustack.ai/latest/tutorials/running-distributed-vllm-with-multiprocessing/" rel="noopener noreferrer"&gt;GPUStack: Running distributed vLLM with the multiprocessing backend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.gpustack.ai/latest/user-guide/inference-backend-management/" rel="noopener noreferrer"&gt;GPUStack inference backend management&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>hardware</category>
      <category>llm</category>
      <category>performance</category>
    </item>
    <item>
      <title>DeepInfer vs. vLLM on 8 B200: Which Is Faster?</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Thu, 22 Oct 2026 07:21:49 +0000</pubDate>
      <link>https://dev.to/gpustack/deepinfer-vs-vllm-on-8x-b200-which-is-faster-4b0l</link>
      <guid>https://dev.to/gpustack/deepinfer-vs-vllm-on-8x-b200-which-is-faster-4b0l</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; We integrated DeepInfer with GPUStack through a lightweight serving project, deployed DeepSeek-V4.1-Flash on a single server with eight NVIDIA B200 GPUs, and compared the resulting service with vLLM under a matched DP8+EP8 setup. In this run, DeepInfer-server delivered higher reported output throughput and shorter inter-token latency, while vLLM achieved lower time to first token and better P95 request latency.&lt;/p&gt;

&lt;p&gt;Efficient inference technology creates business value only when it can be deployed in a real service.&lt;/p&gt;

&lt;p&gt;DeepSeek's open-source DeepInfer gives developers a way to explore its inference technology. Teams that want to run models on their own infrastructure still need to answer several engineering questions: &lt;strong&gt;How do we expose an API? How should the runtime be configured? How do we manage GPUs? And how does the engine perform under a real workload?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To answer those questions, we built a lightweight serving project called &lt;strong&gt;DeepInfer-server&lt;/strong&gt; and integrated it with GPUStack's custom inference backend. The result was a working text-generation service for &lt;strong&gt;DeepSeek-V4.1-Flash on a single server with eight NVIDIA B200 GPUs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article explains the integration, walks through the deployment process, and describes how we compared it with vLLM on the same hardware.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftyijzdm0gx4eby4q7166.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftyijzdm0gx4eby4q7166.png" alt="DeepInfer and vLLM model deployments in GPUStack" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What Does DeepInfer Bring?
&lt;/h2&gt;

&lt;p&gt;DeepInfer is DeepSeek's open-source high-performance inference framework. The current public release provides offline inference and the core engine capabilities required for large-scale serving. It supports DeepSeek-V4.1-Flash and integrates computation and communication components including FlashMLA, DeepGEMM, DeepEP, and DeepSelect. It also supports multiple parallelism strategies, speculative decoding, and asynchronous scheduling. See the &lt;a href="https://github.com/deepseek-ai/DeepInfer" rel="noopener noreferrer"&gt;DeepInfer repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These components optimize different parts of the inference path: computation executes faster, data moves between GPUs more efficiently, and scheduling makes better use of the hardware. What users ultimately care about is how many requests the same resources can serve and how long users have to wait.&lt;/p&gt;

&lt;p&gt;Turning an engine into a production-facing service, however, also requires &lt;strong&gt;request handling, protocol conversion, an HTTP service, and deployment management&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The components in this integration have the following responsibilities:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Role in this integration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DeepInfer&lt;/td&gt;
&lt;td&gt;Runs model inference and manages low-level computation, communication, and parallel execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;deepseek-recipe&lt;/td&gt;
&lt;td&gt;Converts chat requests into model input and parses generated text, reasoning content, and tool calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeepInfer-server&lt;/td&gt;
&lt;td&gt;Connects the components and provides an HTTP API, streaming responses, and service lifecycle management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPUStack&lt;/td&gt;
&lt;td&gt;Manages model deployments, GPU allocation, runtime configuration, and model access and testing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;deepseek-recipe&lt;/strong&gt; is DeepSeek's protocol-conversion and codec component. It translates between API requests, conversation formats, model token sequences, and responses. Model inference and HTTP transport are supplied by the caller. See the &lt;a href="https://github.com/deepseek-ai/deepseek-recipe" rel="noopener noreferrer"&gt;deepseek-recipe repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Build DeepInfer-server?
&lt;/h3&gt;

&lt;p&gt;DeepInfer's current public entry point is primarily designed for offline inference. To start it like &lt;code&gt;vllm serve&lt;/code&gt; and make it callable by applications, the engine must be connected to an HTTP request-processing path. deepseek-recipe handles protocol conversion and output parsing, but the caller must still supply model inference and HTTP transport. Installing both components in the same container does not automatically create a complete online inference service.&lt;/p&gt;

&lt;p&gt;A GPUStack custom-backend definition tells the platform which image and command to run and which arguments to pass. It does not automatically generate an API around an offline engine. This integration therefore needs a connecting layer that organizes the components into a service that can start, report its state, and receive requests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DeepInfer-server provides that serving layer:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connect requests to inference.&lt;/strong&gt; It receives Chat Completions requests, uses deepseek-recipe to convert them into model input, and calls DeepInfer to generate output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return output to applications.&lt;/strong&gt; It converts generated tokens into text, reasoning content, or tool calls; returns standard JSON or SSE streaming responses; and reports token usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manage the service lifecycle.&lt;/strong&gt; It initializes inference processes, handles request dispatch, cancellation, timeouts, and errors, and exposes model-list and health-check endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrate with the deployment platform.&lt;/strong&gt; It provides a container image and common startup arguments so that GPUStack can pass the model path, port, and GPU configuration and then start and manage the service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Applications can therefore call the model through the familiar OpenAI-compatible Chat Completions API, while GPUStack can reuse its custom-backend deployment workflow. DeepInfer still performs the underlying inference, and deepseek-recipe still handles protocol conversion and parsing.&lt;/p&gt;

&lt;p&gt;The current wrapper focuses on &lt;strong&gt;single-node, multi-GPU text inference&lt;/strong&gt;. It is an independent demonstration project for validating the integration. It does not reproduce DeepSeek's complete production architecture for KV-cache management, disaggregated prefill and decode, or load balancing, and it should not be treated as equivalent to DeepSeek's official online service.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Deploying DeepInfer Through a GPUStack Custom Backend
&lt;/h2&gt;

&lt;p&gt;GPUStack's custom inference backend mechanism lets users define a container image, startup command, default parameters, and environment variables so that a new inference service can participate in the normal deployment workflow. Template variables can supply values such as the model path and service port at deployment time. See the &lt;a href="https://docs.gpustack.ai/latest/tutorials/using-custom-backends/" rel="noopener noreferrer"&gt;GPUStack custom backend documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This allows teams to evaluate new inference engines on the same platform while reusing existing model-management and deployment operations.&lt;/p&gt;

&lt;p&gt;The integration includes the following backend definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpustack-deepinfer-server-backend.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Prepare the Runtime Environment
&lt;/h3&gt;

&lt;p&gt;Our demonstration used a single server with eight NVIDIA B200 GPUs and the following model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deepseek-ai/DeepSeek-V4.1-Flash-1017
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2p6u5wfatl8uefs2zobx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2p6u5wfatl8uefs2zobx.png" alt="Eight NVIDIA B200 GPUs in a single server" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before deployment, prepare the complete model weights, the DeepInfer-server image, a compatible GPU driver and container runtime, and sufficient host memory.&lt;/p&gt;

&lt;p&gt;The configuration must also expose the correct RDMA devices and set up the communication environment. The NIC and network parameters in the accompanying YAML come from our validation environment and must be adapted to other servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Import the Custom Backend
&lt;/h3&gt;

&lt;p&gt;On GPUStack's inference-backend management page, create a custom backend and import the &lt;a href="https://github.com/gpustack/DeepInfer-server/blob/main/gpustack-deepinfer-server-backend.yaml" rel="noopener noreferrer"&gt;DeepInfer backend YAML definition&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The definition contains the service startup method, common arguments, health-check path, and JIT-cache directory. At deployment time, GPUStack supplies the model path, service port, model name, and number of allocated GPUs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fosky1kynlqi9uj62r4jx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fosky1kynlqi9uj62r4jx.png" alt="Importing the DeepInfer custom backend in GPUStack" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create the Model Deployment
&lt;/h3&gt;

&lt;p&gt;When creating the model deployment, select the model weights and choose the &lt;code&gt;DeepInfer-server&lt;/code&gt; inference backend created in the previous step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwk93bnn4nwdw0ub09a9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwk93bnn4nwdw0ub09a9x.png" alt="Selecting the DeepInfer-server backend for a model deployment" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To keep the deployment aligned with the benchmark described later, we explicitly set &lt;code&gt;--expert-parallel-size=8&lt;/code&gt;, &lt;code&gt;--data-parallel-size=8&lt;/code&gt;, and &lt;code&gt;--context-parallel-size=1&lt;/code&gt; in the model's backend parameters. These values override the DP=1 default in the supplied YAML. Verify the final startup configuration before launching the service.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Example value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPU count&lt;/td&gt;
&lt;td&gt;8 GPUs in one server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel configuration&lt;/td&gt;
&lt;td&gt;EP=8, DP=8, CP=1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum context length&lt;/td&gt;
&lt;td&gt;32,768 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum running sequences&lt;/td&gt;
&lt;td&gt;16 per DP rank&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batched-token budget&lt;/td&gt;
&lt;td&gt;32,768 per DP rank&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU memory utilization&lt;/td&gt;
&lt;td&gt;Default 0.85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Startup timeout&lt;/td&gt;
&lt;td&gt;3,600 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;EP, DP, and CP refer to expert, data, and context parallelism. The current wrapper requires &lt;code&gt;DP × CP = EP&lt;/code&gt;. We use CP=1 here, so the context is not split across GPUs. &lt;code&gt;max-num-seqs=16&lt;/code&gt; is the limit for each DP rank, giving the DP8 service a total admission limit of 128 sequences.&lt;/p&gt;

&lt;p&gt;The first startup loads the weights and may compile and warm up kernels. Use GPUStack to monitor the startup logs and wait for model initialization to finish before running inference tests. A persistent JIT cache helps reuse compiled artifacts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbiavm5uerrglyaswh2q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbbiavm5uerrglyaswh2q.png" alt="DeepInfer-server initialized and passing its health check" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Verify Inference
&lt;/h3&gt;

&lt;p&gt;After the model is ready, send a text request from the GPUStack Playground to verify streaming output. The same service can then be integrated with existing applications through its API.&lt;/p&gt;

&lt;p&gt;At this point, the full path from model weights and inference engine to API access is working. Teams can continue testing real prompts, monitoring resource utilization, and evaluating the value of further optimization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u2m6wi5856dbs02ucsv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u2m6wi5856dbs02ucsv.png" alt="Verifying DeepInfer inference in the GPUStack Playground" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How Does It Compare with vLLM on the Same Eight B200 GPUs?
&lt;/h2&gt;

&lt;p&gt;Before looking at the numbers, we need to define the scope of this comparison.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This test is a service-integration and preliminary performance validation. Neither deployment was fully tuned for the hardware, and both differ from DeepSeek's production inference architecture. Because the public DeepInfer release does not expose a TP path corresponding to vLLM's tensor parallelism, we configured DeepInfer with CP1, DP8, and EP8 and vLLM with TP1, DP8, and EP8. This makes the parallel strategies more comparable, but &lt;strong&gt;does not represent the best possible configuration for either engine&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;DeepInfer's documented parallelism includes Attention DP or balanced CP and MoE EP with EPLB. Our single-node combined service does not reproduce its production disaggregated prefill/decode architecture, complete KV-cache management, or load balancing. See the &lt;a href="https://github.com/deepseek-ai/DeepInfer" rel="noopener noreferrer"&gt;DeepInfer documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even with DP8+EP8 on both sides, their kernels, communication paths, Engram access, and schedulers are implemented differently. DeepInfer-server also adds request coordination and protocol processing written for this demonstration, and that overhead is included in the end-to-end results. These numbers do not represent the performance of DeepSeek's official service and should not be used to infer the performance ceiling of either engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  First, the Interactive Chat Experience
&lt;/h3&gt;

&lt;p&gt;After deployment, we started with a single-request chat in the GPUStack Playground. In the screenshots, the vLLM deployment produced approximately &lt;strong&gt;91.4 tokens/s&lt;/strong&gt;, while DeepInfer produced approximately &lt;strong&gt;106.2 tokens/s&lt;/strong&gt; in that interaction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvl54uyv8qtrk0acfr5l3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvl54uyv8qtrk0acfr5l3.png" alt="vLLM single-request chat output speed" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A single chat result depends on the prompt, context, answer length, and the UI's measurement method. This screenshot illustrates the interactive experience; it is not a single-request performance ranking and should not be compared directly with the concurrent-output throughput below. For the benchmark, both engines used DP8+EP8, an 8K input, a 1K output, and 16 concurrent requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Environment and Configuration
&lt;/h3&gt;

&lt;p&gt;We used the same eight-B200 server and the same model weights. GPUStack's Benchmark feature issued 100 requests with a target concurrency of 16.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;DeepInfer-server&lt;/th&gt;
&lt;th&gt;vLLM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hardware&lt;/td&gt;
&lt;td&gt;8 × NVIDIA B200 on the same Worker&lt;/td&gt;
&lt;td&gt;8 × NVIDIA B200 on the same Worker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;DeepSeek-V4.1-Flash-1017&lt;/td&gt;
&lt;td&gt;DeepSeek-V4.1-Flash-1017&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version&lt;/td&gt;
&lt;td&gt;DeepInfer commit &lt;code&gt;9bd9cf2&lt;/code&gt;; service image tag &lt;code&gt;latest&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;0.32.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel strategy&lt;/td&gt;
&lt;td&gt;DP8, CP1, EP8&lt;/td&gt;
&lt;td&gt;DP8, TP1, EP8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maximum context length&lt;/td&gt;
&lt;td&gt;32,768 tokens&lt;/td&gt;
&lt;td&gt;32,768 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max-num-seqs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16 per DP rank&lt;/td&gt;
&lt;td&gt;16 per DP rank&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max-num-batched-tokens&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;32,768 per DP rank&lt;/td&gt;
&lt;td&gt;32,768 per DP rank&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU memory utilization&lt;/td&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speculative decoding&lt;/td&gt;
&lt;td&gt;Disabled&lt;/td&gt;
&lt;td&gt;Disabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dataset&lt;/td&gt;
&lt;td&gt;Random&lt;/td&gt;
&lt;td&gt;Random&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target input/output length&lt;/td&gt;
&lt;td&gt;8,192 / 1,024 tokens&lt;/td&gt;
&lt;td&gt;8,192 / 1,024 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target client concurrency&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number of requests&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Raw Results in GPUStack
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp0pq9xnjz23dwk9r13mf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp0pq9xnjz23dwk9r13mf.png" alt="DeepInfer-server benchmark results" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnld5ghgj6otxnwe1o2b6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnld5ghgj6otxnwe1o2b6.png" alt="vLLM benchmark results" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following table places the main metrics side by side:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;DeepInfer-server: DP8+EP8&lt;/th&gt;
&lt;th&gt;vLLM: DP8+EP8&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Successful/total requests&lt;/td&gt;
&lt;td&gt;100 / 100&lt;/td&gt;
&lt;td&gt;100 / 100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean output throughput (tokens/s)&lt;/td&gt;
&lt;td&gt;1,392.44&lt;/td&gt;
&lt;td&gt;1,112.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean time to first token, TTFT (s)&lt;/td&gt;
&lt;td&gt;4.28&lt;/td&gt;
&lt;td&gt;2.04&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P95 time to first token, TTFT (s)&lt;/td&gt;
&lt;td&gt;16.33&lt;/td&gt;
&lt;td&gt;8.27&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean inter-token latency, ITL (ms)&lt;/td&gt;
&lt;td&gt;8.74&lt;/td&gt;
&lt;td&gt;11.98&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P95 inter-token latency, ITL (ms)&lt;/td&gt;
&lt;td&gt;8.93&lt;/td&gt;
&lt;td&gt;13.70&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean end-to-end request latency (s)&lt;/td&gt;
&lt;td&gt;13.23&lt;/td&gt;
&lt;td&gt;14.30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;P95 end-to-end request latency (s)&lt;/td&gt;
&lt;td&gt;25.46&lt;/td&gt;
&lt;td&gt;20.03&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actual mean concurrency&lt;/td&gt;
&lt;td&gt;14.72&lt;/td&gt;
&lt;td&gt;14.58&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Output throughput, TTFT, ITL, and request latency come from the exported report's &lt;code&gt;output_tokens_per_second_mean&lt;/code&gt;, &lt;code&gt;time_to_first_token_*&lt;/code&gt;, &lt;code&gt;inter_token_latency_*&lt;/code&gt;, and &lt;code&gt;request_latency_*&lt;/code&gt; fields. The table converts TTFT from milliseconds to seconds. Output throughput retains the report's mean statistic and is not converted into whole-run duration. ITL is not mixed with the report's &lt;code&gt;time_per_output_token&lt;/code&gt; or per-SSE-chunk intervals.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. What Do These Results Tell Us?
&lt;/h2&gt;

&lt;p&gt;In these two DP8+EP8 runs, &lt;strong&gt;DeepInfer-server reported higher mean output throughput and shorter mean inter-token latency&lt;/strong&gt;, while &lt;strong&gt;vLLM delivered a shorter time to first token and lower tail latency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;DeepInfer-server's reported mean output throughput was approximately &lt;strong&gt;25.2% higher&lt;/strong&gt; than vLLM's corresponding run. Its mean ITL was approximately &lt;strong&gt;27.0% lower&lt;/strong&gt;, and its mean end-to-end request latency was approximately &lt;strong&gt;7.5% lower&lt;/strong&gt;. These are differences between two specific test runs; they are not yet proof of a stable performance advantage.&lt;/p&gt;

&lt;p&gt;At the same time, DeepInfer-server's mean TTFT was 4.28 seconds, about &lt;strong&gt;2.09×&lt;/strong&gt; vLLM's 2.04 seconds. Its P95 request latency was 25.46 seconds, approximately &lt;strong&gt;27.1% higher&lt;/strong&gt; than vLLM's 20.03 seconds. The wait before an answer begins and the experience of the slowest requests both leave room for improvement.&lt;/p&gt;

&lt;p&gt;The result demonstrates why an inference service should be evaluated across &lt;strong&gt;throughput, time to first token, sustained generation speed, and tail latency&lt;/strong&gt;. Interactive applications benefit from beginning a response quickly, while batch-generation workloads also care about how much output can be completed per unit of time. No single metric fully describes the service experience.&lt;/p&gt;

&lt;p&gt;Both DP8+EP8 configurations completed all 100 requests, validating service availability under this test load. One hundred successful requests are not equivalent to production stability certification, and the Random dataset does not evaluate answer quality.&lt;/p&gt;

&lt;p&gt;For GPUStack, the experiment demonstrates a reusable workflow: &lt;strong&gt;integrate a new engine through a custom backend, deploy and test it on one platform, and use measured data to choose the runtime that fits the workload&lt;/strong&gt;. We plan to continue testing fixed prompts and controlled conditions at different concurrency levels, and to separate the overhead of the serving wrapper from engine execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Continuing the Work to Make Efficient Inference Easier to Use
&lt;/h2&gt;

&lt;p&gt;DeepInfer's open-source release gives the community more inference-optimization techniques that can be studied and validated.&lt;/p&gt;

&lt;p&gt;In its deployment Q&amp;amp;A, DeepSeek explains that its KV-cache management and load-balancing components are tightly coupled to internal infrastructure and have not yet been fully open sourced. DeepSeek also states that &lt;strong&gt;inference code and performance optimizations for future DeepSeek models&lt;/strong&gt; will continue to be released through DeepInfer. See the &lt;a href="https://github.com/deepseek-ai/DeepInfer/blob/main/doc/inference_deployment_qa.md" rel="noopener noreferrer"&gt;DeepSeek inference deployment Q&amp;amp;A&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This creates room for future integration work. The timing and scope of any additional open-source components should still be based on DeepSeek's official announcements.&lt;/p&gt;

&lt;p&gt;GPUStack will continue following DeepInfer and the related computation, communication, and codec components. As components become available and verifiable, we will evaluate further integration through real deployments and tests.&lt;/p&gt;

&lt;p&gt;Our goal is to help new inference technology reach developers and enterprises faster: lower the barrier to experimentation, make performance gains reproducible, make infrastructure cost measurable, and enable more teams to run large models effectively and affordably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Making low-cost inference broadly accessible&lt;/strong&gt; requires sustained technical optimization—and it also requires making those optimizations easier to deploy and use.&lt;/p&gt;

&lt;p&gt;GPUStack: &lt;a href="https://github.com/gpustack/gpustack" rel="noopener noreferrer"&gt;github.com/gpustack/gpustack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DeepInfer-server: &lt;a href="https://github.com/gpustack/DeepInfer-server" rel="noopener noreferrer"&gt;github.com/gpustack/DeepInfer-server&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>testing</category>
      <category>llm</category>
    </item>
    <item>
      <title>GPUStack Jev: Decision Routing — Mechanism, Configuration, and Validation</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Mon, 12 Oct 2026 09:36:06 +0000</pubDate>
      <link>https://dev.to/gpustack/gpustack-x-jev-decision-routing-mechanism-configuration-and-validation-3m9l</link>
      <guid>https://dev.to/gpustack/gpustack-x-jev-decision-routing-mechanism-configuration-and-validation-3m9l</guid>
      <description>&lt;p&gt;GPUStack v2.3.0rc2 introduced a preview of an advanced routing capability worth testing hands-on: selecting a model through the Jev decision service.&lt;/p&gt;

&lt;p&gt;When multiple models are available in GPUStack, an application would normally need to specify which one to call. With decision routing enabled, the application can always use the same entry point. The gateway then chooses a generation model based on the task content and the policy defined by the administrator.&lt;/p&gt;

&lt;p&gt;This article follows that path end to end. We first introduce decision models, then deploy two private models in GPUStack, connect DeepSeek and Jev, and finally use tasks of different difficulty levels to verify the resulting model selections.&lt;/p&gt;

&lt;h2&gt;
  
  
  01 What Is a Decision Model?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Generation models answer questions&lt;/strong&gt;. &lt;strong&gt;Decision models provide evidence for choosing a model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, “Translate Good morning into Chinese” and “Design a cross-region payment system” require different capabilities. A smaller model may be sufficient for the first task, while the second may require a stronger model to reason about failures and consistency.&lt;/p&gt;

&lt;p&gt;Jev receives the request content, candidate models, and their capability descriptions. It returns structured selection evidence through the &lt;a href="https://docs.typesafe.ai/primitives/choice.md" rel="noopener noreferrer"&gt;TypeSafe Choice interface&lt;/a&gt;. The GPUStack gateway uses that evidence to choose a model and then forwards the request to the selected generation service. The final answer still comes from Qwen3 or DeepSeek.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgpo2mp3bh8a1feudz1ph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgpo2mp3bh8a1feudz1ph.png" alt="One request: decide first, then generate" width="800" height="696"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key to configuring decision routing is therefore to describe clearly which tasks each candidate model is suited for. A decision model does not establish business-quality standards on behalf of the administrator. The closer the capability descriptions are to real workloads, the easier the selections are to validate.&lt;/p&gt;

&lt;h2&gt;
  
  
  02 What Problem Does Jev Solve in the Gateway?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.gpustack.ai/2.1/tutorials/managing-model-routes/" rel="noopener noreferrer"&gt;GPUStack model routing&lt;/a&gt; can place multiple targets behind one entry point. Fixed weights answer the question “How much traffic should each model receive?” and are useful for canary releases and traffic distribution. Jev decision routing goes one step further and asks “Which model is appropriate for this request?”&lt;/p&gt;

&lt;p&gt;For an assistant that handles both text and code, we want the following division of work:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task type&lt;/th&gt;
&lt;th&gt;Candidate in this policy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Short translation, field extraction, factual questions, and basic arithmetic&lt;/td&gt;
&lt;td&gt;Private Qwen3-8B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Constrained algorithm implementation, SQL, and localized code debugging&lt;/td&gt;
&lt;td&gt;Private Qwen3-32B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complex concurrent code and cross-region system design&lt;/td&gt;
&lt;td&gt;External DeepSeek&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The application uses one route name, while the administrator maintains this division of work in GPUStack. Candidates can be added or task boundaries adjusted without changing how the application calls the route.&lt;/p&gt;

&lt;p&gt;This is the gateway-level value of a decision model: &lt;strong&gt;centralize task classification in the routing policy&lt;/strong&gt; so that different models handle the requests best suited to them. Whether this improves quality or reduces cost still has to be validated against real workloads. This article first checks whether task routing follows the configured policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  03 Prepare the Models and External Services
&lt;/h2&gt;

&lt;p&gt;First, prepare the three candidates that will generate answers. Then connect Jev as the service responsible for making the decision.&lt;/p&gt;

&lt;p&gt;Deploy Qwen3-8B and Qwen3-32B-W8A8 through GPUStack. Both models should show one available replica out of one. Send an inference request to each model to confirm that both can answer successfully.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4i3lrbpqzjk7d8yi1qu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4i3lrbpqzjk7d8yi1qu.png" alt="Qwen3-8B and Qwen3-32B-W8A8 deployments" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, add DeepSeek under Providers. Select the DeepSeek type, enter the API key, and test connectivity. The generation model used in this test is &lt;code&gt;deepseek-flash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foz60llvxs3rmm1yktv1d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foz60llvxs3rmm1yktv1d.png" alt="Add the DeepSeek provider" width="800" height="1533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add Jev as another provider. Select TypeSafe Decision Service (Jev), set the endpoint to &lt;code&gt;https://api.typesafe.ai&lt;/code&gt;, and enter the TypeSafe API key. This test uses &lt;code&gt;jev-latest&lt;/code&gt; as the decision model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgiwd2ks623m2driln487.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgiwd2ks623m2driln487.png" alt="Add the Jev decision service" width="800" height="1533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point, the responsibilities are separate. &lt;strong&gt;Qwen3 and DeepSeek are route targets&lt;/strong&gt; and generate answers. &lt;strong&gt;Jev is the decision service&lt;/strong&gt; and provides evidence that helps the gateway choose a target.&lt;/p&gt;

&lt;h2&gt;
  
  
  04 Configure a Decision Route
&lt;/h2&gt;

&lt;p&gt;Create a route named &lt;code&gt;demo-smart&lt;/code&gt; and add the two private deployments and the DeepSeek model as regular route targets. The application only needs to request &lt;code&gt;demo-smart&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F10a4st6dtx6kft44myii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F10a4st6dtx6kft44myii.png" alt="The demo-smart route and its three targets" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Under Basic Information, select Policy, enable Decision Service Routing, choose the Jev provider &lt;code&gt;routing-jev&lt;/code&gt;, and enter &lt;code&gt;jev-latest&lt;/code&gt; as the decision model.&lt;/p&gt;

&lt;p&gt;In this test, all three ordinary traffic weights are set to 0, while the decision contribution weight is set to 20 so that the effect of Jev is easy to observe. &lt;strong&gt;The decision contribution weight is a relative influence on the score&lt;/strong&gt;. It is not a traffic percentage. Session stickiness and the least-outstanding-requests strategy are not combined with it in this test.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F39pl4pcc17v6yslqfwcx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F39pl4pcc17v6yslqfwcx.png" alt="Decision service, decision model, instructions, and evaluation criteria" width="800" height="1733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffx3u7z2qptlexnezgfsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffx3u7z2qptlexnezgfsw.png" alt="Route targets and fallback route target" width="800" height="1733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, define the Decision Instructions and Model Evaluation Criteria. Together, they answer two questions: What is the overall selection principle, and what tasks is each candidate suited for?&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Core content used in this test&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Decision instructions&lt;/td&gt;
&lt;td&gt;Prefer the least expensive candidate that can complete the task. Send simple tasks to 8B, medium-complexity tasks to 32B, and complex tasks to DeepSeek.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8B capability description&lt;/td&gt;
&lt;td&gt;Suitable for short translation, extraction, factual questions, short summaries, and basic arithmetic. The service context budget is 8,192 tokens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32B capability description&lt;/td&gt;
&lt;td&gt;Suitable for SQL, algorithm implementation, and localized debugging. The service context budget is 16,384 tokens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeepSeek capability description&lt;/td&gt;
&lt;td&gt;Suitable for complex reasoning, concurrent code with tests, and distributed architecture design.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The keys in the capability descriptions must match the actual candidate model names: &lt;code&gt;route-local-qwen3-8b&lt;/code&gt;, &lt;code&gt;route-local-qwen3-32b&lt;/code&gt;, and &lt;code&gt;deepseek-flash&lt;/code&gt;. &lt;strong&gt;Do not use route aliases or provider names&lt;/strong&gt; because they cannot be mapped to the candidates.&lt;/p&gt;

&lt;p&gt;This capability split is a policy to be validated. The assumption that 8B is the lower-cost tier, 32B is the middle tier, and DeepSeek is the higher tier is also part of the configuration. This test does not calculate hardware amortization or API charges.&lt;/p&gt;

&lt;h2&gt;
  
  
  05 Validate Three Model Choices Through One Route
&lt;/h2&gt;

&lt;p&gt;Every test in this section uses the same route, &lt;code&gt;demo-smart&lt;/code&gt;. The nine test inputs are nine questions, not nine routes. Only the question content changes. The &lt;code&gt;model&lt;/code&gt; field remains unchanged while we observe whether the gateway follows the configured division of work and selects 8B, 32B, or DeepSeek.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Write Down the Expected Results
&lt;/h3&gt;

&lt;p&gt;Start with three representative inputs. A short translation is expected to go to 8B, constrained interval-merging code to 32B, and cross-region payment-system design to DeepSeek. Recording the expectations first prevents us from explaining the choice only after seeing the answer.&lt;/p&gt;

&lt;p&gt;Select &lt;code&gt;demo-smart&lt;/code&gt; in the GPUStack Playground to confirm that the route can complete a conversation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb6bzpvgkmf4blicgnnxh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb6bzpvgkmf4blicgnnxh.png" alt="Use demo-smart in the Playground" width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Send the Request and Retain the Headers and Answer
&lt;/h3&gt;

&lt;p&gt;Use the API for the formal test so that the selected model can be traced. First, create a GPUStack inference key and save the following content as &lt;code&gt;request.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"demo-smart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Translate ‘Good morning’ into Chinese. Return only the translation."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"temperature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stream"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chat_template_kwargs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enable_thinking"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"thinking"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"disabled"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Send the request to the gateway, saving the response headers to &lt;code&gt;response.headers&lt;/code&gt; and the answer to &lt;code&gt;response.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sS&lt;/span&gt; http://localhost:9080/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-D&lt;/span&gt; response.headers &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; response.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$GPUSTACK_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data-binary&lt;/span&gt; @request.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the next test, change only the question in &lt;code&gt;messages&lt;/code&gt; and increase &lt;code&gt;max_tokens&lt;/code&gt; for code or longer answers. Keep &lt;code&gt;model&lt;/code&gt; set to &lt;code&gt;demo-smart&lt;/code&gt;. The interval-merging test uses a 1,024-token output budget, and the system-design test uses 1,536 tokens. Replace the gateway address with the address of your own deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Find the Actual Model by Request ID
&lt;/h3&gt;

&lt;p&gt;Read &lt;code&gt;x-gpustack-request-id&lt;/code&gt; from the response headers, then use it to locate the corresponding Higress log entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REQUEST_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'tolower($1)=="x-gpustack-request-id:" {gsub("\r", "", $2); print $2}'&lt;/span&gt; response.headers&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REQUEST_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'response header does not contain a request ID'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

kubectl &lt;span class="nt"&gt;--context&lt;/span&gt; gateway-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-n&lt;/span&gt; inference-gateway logs deployment/higress-gateway &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;500 &lt;span class="se"&gt;\&lt;/span&gt;
  | rg &lt;span class="nt"&gt;--fixed-strings&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REQUEST_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the context and namespace with your own gateway configuration. In the matching log entry, inspect &lt;code&gt;upstream_cluster&lt;/code&gt; to identify the forwarding target and &lt;code&gt;ai_log.model&lt;/code&gt; to confirm the model name. In this test, &lt;code&gt;model-2-6.static&lt;/code&gt; maps to 8B, &lt;code&gt;model-3-7.static&lt;/code&gt; maps to 32B, and &lt;code&gt;provider-1.dns&lt;/code&gt; maps to DeepSeek. These identifiers change with the deployment.&lt;/p&gt;

&lt;p&gt;The evidence is &lt;strong&gt;the request with one request ID&lt;/strong&gt;, &lt;strong&gt;its response&lt;/strong&gt;, and &lt;strong&gt;the matching access log&lt;/strong&gt;. An HTTP 200 status only confirms that the request succeeded. It does not prove which model was selected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Compare the Measured Results
&lt;/h3&gt;

&lt;p&gt;The next three figures show the request, response headers and body excerpt, and matching gateway log fields from the archived API test. Each figure retains the request ID. The entry point remains the same, while the model that generates the answer changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Short translation&lt;/strong&gt; → &lt;strong&gt;8B&lt;/strong&gt;. The request asks for a short translation of “Good morning.” The model returned the expected translation, while the log records &lt;code&gt;route-local-qwen3-8b&lt;/code&gt; and upstream &lt;code&gt;model-2-6.static&lt;/code&gt;. The figure localizes the body excerpt into English for this edition while preserving the request ID and routing evidence.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fonkwxlz6qbn6wx9nufb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fonkwxlz6qbn6wx9nufb1.png" alt="Short translation selected Qwen3-8B" width="800" height="1300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constrained code&lt;/strong&gt; → &lt;strong&gt;32B&lt;/strong&gt;. The task asks for interval merging without modifying the input and requires invalid intervals to be rejected. The API returned Python code, while the log records &lt;code&gt;route-local-qwen3-32b&lt;/code&gt; and upstream &lt;code&gt;model-3-7.static&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5knsopm366o5mfhpvljf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5knsopm366o5mfhpvljf.png" alt="Constrained code selected Qwen3-32B" width="800" height="1788"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross-region system design&lt;/strong&gt; → &lt;strong&gt;DeepSeek&lt;/strong&gt;. The task asks for an analysis of payment callbacks, inventory deductions, network partitions, and recovery reconciliation. The API returned a design explanation, while the log records &lt;code&gt;deepseek-flash&lt;/code&gt; and upstream &lt;code&gt;provider-1.dns&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frnvtfqh899uefu7kgghe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frnvtfqh899uefu7kgghe.png" alt="Cross-region system design selected DeepSeek" width="800" height="1556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to these three representative inputs, we tested factual questions, extraction, arithmetic, SQL, and other tasks. All nine inputs went through &lt;code&gt;demo-smart&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test input&lt;/th&gt;
&lt;th&gt;Expected model&lt;/th&gt;
&lt;th&gt;Actual model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Capital of France&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Short translation of Good morning&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract a city from text&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Calculate 2+2&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;td&gt;8B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Constrained interval-merging code&lt;/td&gt;
&lt;td&gt;32B&lt;/td&gt;
&lt;td&gt;32B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PostgreSQL aggregation query&lt;/td&gt;
&lt;td&gt;32B&lt;/td&gt;
&lt;td&gt;32B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analyze and fix an asynchronous-lock deadlock&lt;/td&gt;
&lt;td&gt;32B&lt;/td&gt;
&lt;td&gt;32B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-region order-payment system design&lt;/td&gt;
&lt;td&gt;DeepSeek&lt;/td&gt;
&lt;td&gt;DeepSeek&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Asynchronous LRU cache with tests&lt;/td&gt;
&lt;td&gt;DeepSeek&lt;/td&gt;
&lt;td&gt;DeepSeek&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All nine requests returned HTTP 200 with &lt;code&gt;stop&lt;/code&gt; as the finish reason, and every actual model matched the expectation. This verifies that the configured task split can be implemented behind one entry point. The translation, interval-merging, and system-design tests were each repeated three times as non-streaming requests, and the model selection remained stable. Streaming versions of all three tasks also selected the same models.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selecting the Right Model Is Not the Same as Accepting Its Answer
&lt;/h3&gt;

&lt;p&gt;To determine whether this division of work had a concrete basis, we sent the same translation, extraction, arithmetic, and interval-merging tasks to all three candidates with identical input and output budgets.&lt;/p&gt;

&lt;p&gt;The code task required correct interval merging, no mutation of the input, and a &lt;code&gt;ValueError&lt;/code&gt; for an invalid interval. The generated code was executed in an isolated environment.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Acceptance check&lt;/th&gt;
&lt;th&gt;8B&lt;/th&gt;
&lt;th&gt;32B&lt;/th&gt;
&lt;th&gt;DeepSeek&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Short translation, city extraction, and 2+2&lt;/td&gt;
&lt;td&gt;All correct&lt;/td&gt;
&lt;td&gt;All correct&lt;/td&gt;
&lt;td&gt;All correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merge results, empty input, and touching endpoints&lt;/td&gt;
&lt;td&gt;Passed&lt;/td&gt;
&lt;td&gt;Passed&lt;/td&gt;
&lt;td&gt;Passed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does not modify the original input&lt;/td&gt;
&lt;td&gt;Failed&lt;/td&gt;
&lt;td&gt;Passed&lt;/td&gt;
&lt;td&gt;Passed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raises &lt;code&gt;ValueError&lt;/code&gt; for an invalid interval&lt;/td&gt;
&lt;td&gt;Failed&lt;/td&gt;
&lt;td&gt;Passed&lt;/td&gt;
&lt;td&gt;Passed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The 8B answer modified the original input and omitted the invalid-interval check. The 32B and DeepSeek answers met both constraints. This provides specific evidence for routing constrained algorithm implementations to 32B, but it does not establish a general ranking of model capability.&lt;/p&gt;

&lt;p&gt;The asynchronous-cache code generated by DeepSeek passed its three included tests, but the logs still contained an unhandled Future exception. &lt;strong&gt;Outputs from a stronger model still require independent validation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Happens When the Jev Decision Service Fails?
&lt;/h3&gt;

&lt;p&gt;Model selection depends on Jev returning valid decision evidence. If Jev is unreachable, times out, or returns an invalid result, the decision plugin does not publish a ranking opinion. The gateway continues with the remaining selection and forwarding process. This is &lt;code&gt;fail-open&lt;/code&gt; behavior.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft4wwrhhhojvqiibly8z5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft4wwrhhhojvqiibly8z5.png" alt="Fail-open behavior when the Jev decision service fails" width="800" height="862"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In an isolated failure-test route, we configured an unreachable Jev endpoint while keeping all three generation candidates healthy. The log showed &lt;code&gt;publishing no rank&lt;/code&gt;. DeepSeek happened to answer, and the final response was HTTP 200. This demonstrates that processing can continue after a decision failure. It does not mean that failures always route to DeepSeek.&lt;/p&gt;

&lt;p&gt;Another input of approximately 79 KB did not succeed. Jev returned 400 and published no ranking opinion. The request then entered the 32B target, which also returned 400 because its context budget was insufficient. &lt;strong&gt;When no decision ranking is available&lt;/strong&gt;, &lt;strong&gt;the gateway cannot guarantee selection of a model that meets the task requirements&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A separate translation prompt that instructed the system to ignore the policy and choose DeepSeek still went to 8B, but its answer did not satisfy the request. This again shows that &lt;strong&gt;model selection and answer quality must be evaluated separately&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  06 Return to the Gateway and Follow the Complete Call Path
&lt;/h2&gt;

&lt;p&gt;After the configuration and validation steps, the &lt;a href="https://docs.gpustack.ai/latest/architecture/" rel="noopener noreferrer"&gt;division of responsibilities between GPUStack and the gateway&lt;/a&gt; becomes easier to understand.&lt;/p&gt;

&lt;p&gt;GPUStack manages candidate models, providers, and routing policies, then synchronizes the configuration to Higress. When a request reaches the gateway, plugins prepare the candidate information, the decision plugin calls Jev for selection evidence, and the gateway chooses an upstream target before forwarding the request to a private model or DeepSeek.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3c61asq945v9vz8n8hre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3c61asq945v9vz8n8hre.png" alt="Higress decision-routing request-processing architecture" width="800" height="1214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Jev call and the generation call are two different paths. Jev participates in model selection. Qwen3 or DeepSeek generates the answer. If the decision call does not produce valid evidence, the request may continue, but selection of the expected model is no longer guaranteed.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Deeper Look at How the Plugin Uses Jev Results
&lt;/h3&gt;

&lt;p&gt;To understand how the gateway processes Jev’s evidence internally, read the next figure from top to bottom. The plugin prepares the candidates and task descriptions, calls Jev, converts the returned model probabilities into candidate scores, and lets the load-balancing finisher aggregate the scores and select an upstream target.&lt;/p&gt;

&lt;p&gt;The diagram is based on commit &lt;code&gt;790256e&lt;/code&gt; of the &lt;a href="https://github.com/gpustack/gpustack-higress-plugin/tree/main/extensions/gpustack-lb-decision-service" rel="noopener noreferrer"&gt;decision-plugin source code&lt;/a&gt;. The probabilities and confidence value in the diagram illustrate the calculation and are not measured responses from the preceding tests. Confidence adjusts the influence of the decision opinion. It is not the probability that an answer is correct.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqvjjcpg1mc1e81jw7ojf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqvjjcpg1mc1e81jw7ojf.png" alt="Decision-model plugin flow from task to ranking opinion" width="800" height="1866"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the application, the entry point always remains &lt;code&gt;demo-smart&lt;/code&gt;. For the administrator, the work is to maintain the capability boundaries of the candidate models and continuously validate selections against representative tasks. This is the value of decision routing: put the “&lt;strong&gt;which model should handle this request&lt;/strong&gt;” decision into the gateway so that multi-model specialization becomes a configurable and testable policy.&lt;/p&gt;

&lt;p&gt;This validation covered 36 requests: 9 distinct inputs through the same &lt;code&gt;demo-smart&lt;/code&gt; route, 12 same-task baselines, 6 additional repetitions, 3 streaming requests, and 6 failure or policy-control cases. Routing and transport met their respective criteria, while answer quality was evaluated separately. The article focuses on the capability introduced in v2.3.0rc2 and uses a development environment with Server baseline &lt;code&gt;f0c237f&lt;/code&gt; and UI baseline &lt;code&gt;5a4fc16&lt;/code&gt;. &lt;strong&gt;It does not include sustained-concurrency testing or a cost-benefit analysis&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/gpustack/gpustack/releases/tag/v2.3.0rc2" rel="noopener noreferrer"&gt;GPUStack v2.3.0rc2 Release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.typesafe.ai/primitives/choice.md" rel="noopener noreferrer"&gt;TypeSafe Choice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.gpustack.ai/2.1/tutorials/managing-model-routes/" rel="noopener noreferrer"&gt;GPUStack Model Routing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.gpustack.ai/latest/architecture/" rel="noopener noreferrer"&gt;GPUStack Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gpustack/gpustack-higress-plugin/tree/main/extensions/gpustack-lb-decision-service" rel="noopener noreferrer"&gt;gpustack-lb-decision-service Source&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>jev</category>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
    </item>
    <item>
      <title>Can an NVIDIA A800 80GB Run Qwen-Image-2.1? A GPUStack Deployment Guide</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Thu, 08 Oct 2026 10:08:29 +0000</pubDate>
      <link>https://dev.to/gpustack/can-an-nvidia-a800-80gb-run-qwen-image-21-a-gpustack-deployment-guide-jfj</link>
      <guid>https://dev.to/gpustack/can-an-nvidia-a800-80gb-run-qwen-image-21-a-gpustack-deployment-guide-jfj</guid>
      <description>&lt;p&gt;On September 20, 2026, the Qwen team open-sourced &lt;strong&gt;Qwen-Image-2.1&lt;/strong&gt;, a model that unifies text-to-image generation and image editing. Its visual generation component is a &lt;strong&gt;7B-parameter, 32-layer Single-Stream DiT&lt;/strong&gt;, while text and conditioning-image encoding are handled by &lt;strong&gt;Qwen3-VL-8B&lt;/strong&gt;. The team describes it as a compact image model designed to balance efficiency and general-purpose capability.&lt;/p&gt;

&lt;p&gt;Here are the key specifications reported by the project and community testing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Specification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Intended use&lt;/td&gt;
&lt;td&gt;Unified text-to-image and image-editing model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visual generation component&lt;/td&gt;
&lt;td&gt;7B parameters; 32-layer Single-Stream DiT (Block-Causal attention)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text/conditioning encoder&lt;/td&gt;
&lt;td&gt;Qwen3-VL-8B (text instructions and reference images use the same encoding path)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Core pipeline parameter count&lt;/td&gt;
&lt;td&gt;Approximately 16B (the ModelScope repository lists 16.22B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VAE&lt;/td&gt;
&lt;td&gt;64-channel RGBA autoencoder with 16× spatial compression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resolution&lt;/td&gt;
&lt;td&gt;Native 2K; 2048 × 2048 by default; seven aspect ratios, up to 2752 × 1536&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference&lt;/td&gt;
&lt;td&gt;Flow Matching with the Euler scheduler; 40 steps recommended. Service defaults may differ.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference images&lt;/td&gt;
&lt;td&gt;The model supports up to 10; the current vLLM-Omni recipe allows up to 4 per request.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transparency&lt;/td&gt;
&lt;td&gt;Native RGBA output, with the alpha channel generated directly in latent space&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Checkpoint size&lt;/td&gt;
&lt;td&gt;Approximately 33 GB (ModelScope repository)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;Qwen Research License (&lt;strong&gt;limited to non-commercial research and evaluation&lt;/strong&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6hco0y2o4zhz7upbq1n7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6hco0y2o4zhz7upbq1n7.png" alt="Qwen-Image-2.1 specifications and benchmarks" width="799" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The four upgrades highlighted by the Qwen team are &lt;strong&gt;a more compact and efficient architecture&lt;/strong&gt; (the DiT shrinks from 20.4B parameters in the previous generation to 7B), &lt;strong&gt;native transparent-image generation&lt;/strong&gt; (RGBA layers can be generated and edited directly), &lt;strong&gt;more flexible multi-image and local editing&lt;/strong&gt; (the model supports up to 10 reference images, subject to backend limits), and &lt;strong&gt;improvements to text rendering and portrait lighting details&lt;/strong&gt;. On transparency, the ComfyUI blog puts it this way: “No other major open model does this.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Deploy Qwen-Image-2.1 on GPUStack
&lt;/h2&gt;

&lt;p&gt;Qwen-Image-2.1 is a diffusion (DiT) model, not an autoregressive LLM, so &lt;strong&gt;it cannot be run with conventional vLLM alone&lt;/strong&gt;. It uses &lt;strong&gt;vLLM-Omni&lt;/strong&gt;, the vLLM project's runtime for diffusion and multimodal generation models. The Qwen team announced support on the model's release day (Day 0).&lt;/p&gt;

&lt;p&gt;The workflow in GPUStack is similar to deploying an LLM: &lt;strong&gt;first add a vLLM version that points to a vLLM-Omni image under Inference Backends&lt;/strong&gt;. The rest of the deployment can be completed in the web interface.&lt;/p&gt;

&lt;p&gt;Test environment: NVIDIA A800-SXM4-80GB; driver 570.172.08; CUDA 12.8.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Add a vLLM-Omni version under Inference Backends
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important: Add the image version under Inference Backends first.&lt;/strong&gt; It will then appear in the &lt;strong&gt;Backend Version&lt;/strong&gt; dropdown on the deployment page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the left-hand menu, open &lt;strong&gt;Inference Backends&lt;/strong&gt;, find the vLLM card, and click &lt;strong&gt;Edit&lt;/strong&gt;. Under &lt;strong&gt;Version Configuration&lt;/strong&gt;, click &lt;strong&gt;Add Version&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Version&lt;/strong&gt;: &lt;code&gt;qwen-image21&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image&lt;/strong&gt;: &lt;code&gt;vllm/vllm-omni:qwen-image21&lt;/code&gt; (the image tag used in this guide). &lt;strong&gt;Verify that this image was built with the Qwen-Image-2.1 integration.&lt;/strong&gt; At the time this guide was checked, the vLLM recipe said support had not yet been included in a versioned release package and that the corresponding branch should be used. An image tag alone does not prove that it is an official release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Framework&lt;/strong&gt;: Select &lt;strong&gt;CUDA&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Keep the default image entrypoint (&lt;code&gt;ENTRYPOINT&lt;/code&gt;), &lt;code&gt;vllm serve&lt;/code&gt;. Add &lt;code&gt;--omni&lt;/code&gt; to the default command template, for example: &lt;code&gt;{{model_path}} --omni --host {{worker_ip}} --port {{port}} --served-model-name {{model_name}}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Save the configuration. You can then select &lt;code&gt;qwen-image21&lt;/code&gt; on the deployment page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz6jo8bds3c23gebgoccg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz6jo8bds3c23gebgoccg.png" alt="GPUStack Inference Backends version configuration — English-localized from the genuine UI screenshot" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Image and startup command:&lt;/strong&gt; Qwen-Image-2.1 requires the diffusion implementation in vLLM-Omni and must be launched with &lt;code&gt;vllm serve &amp;lt;model-name&amp;gt; --omni&lt;/code&gt;. Make sure the image contains the required model code and that GPUStack actually passes &lt;code&gt;--omni&lt;/code&gt; to the process. A standard vLLM image or a configuration that omits this argument will not run the example as shown.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2) Create a deployment and select the model and backend
&lt;/h3&gt;

&lt;p&gt;Return to &lt;strong&gt;Deployments&lt;/strong&gt; and click &lt;strong&gt;Deploy Model&lt;/strong&gt; in the upper-right corner. Enter the following settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source&lt;/strong&gt;: Select &lt;strong&gt;ModelScope&lt;/strong&gt; (this guide uses ModelScope; choose a model source based on your network environment and organizational policy) and enter the repository ID &lt;code&gt;Qwen/Qwen-Image-2.1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Select &lt;strong&gt;vLLM&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend Version&lt;/strong&gt;: Select the &lt;code&gt;qwen-image21&lt;/code&gt; version you just added.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Submit the deployment and wait for the instance to reach &lt;strong&gt;Running&lt;/strong&gt;. If the model fails to load, check the image version, the &lt;code&gt;--omni&lt;/code&gt; startup argument, and access permissions for the model repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0h08dmcovwn02fuvbpue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0h08dmcovwn02fuvbpue.png" alt="GPUStack deployment page showing Qwen-Image-2.1 — English-localized from the genuine UI screenshot" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Verify and call the service
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Generate an image through an OpenAI-compatible API
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;--omni&lt;/code&gt; mode, vLLM-Omni registers two OpenAI-compatible endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/v1/images/generations&lt;/code&gt;: standard image-generation endpoint&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/v1/chat/completions&lt;/code&gt;: chat endpoint that supports multimodal input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;/v1/chat/completions&lt;/code&gt; endpoint uses a multimodal message structure: &lt;code&gt;messages[].content&lt;/code&gt; is an array, and prompt text goes in a &lt;code&gt;text&lt;/code&gt; item. To generate an image, also set &lt;code&gt;modalities: ["image"]&lt;/code&gt; in the request body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8000/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;API_KEY&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "qwen-image-2.1",
    "messages": [
      {
        "role": "user",
        "content": [
          {"type": "text", "text": "A golden retriever running through a grassy field, backlit, cinematic lighting."}
        ]
      }
    ],
    "modalities": ["image"],
    "extra_body": {
      "size": "1024x1024",
      "num_inference_steps": 40,
      "true_cfg_scale": 1.0,
      "seed": 42
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkjvdwvn2kvjuap02y9mz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkjvdwvn2kvjuap02y9mz.png" alt="Generated golden retriever image" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To edit an image using a reference, add an &lt;code&gt;image_url&lt;/code&gt; item to &lt;code&gt;content&lt;/code&gt;, while keeping &lt;code&gt;modalities: ["image"]&lt;/code&gt; and the image-generation parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Extract the main subject from the reference image as a layer with a transparent background."&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"image_url"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"image_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"data:image/png;base64,&amp;lt;REFERENCE_IMAGE_BASE64&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request parameter notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;model&lt;/code&gt;&lt;/strong&gt;: Use the same model name that you specified when creating the deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;messages[].content&lt;/code&gt;&lt;/strong&gt;: Use the array structure; put the prompt in a &lt;code&gt;text&lt;/code&gt; item and the reference image in an &lt;code&gt;image_url&lt;/code&gt; item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;image_url.url&lt;/code&gt;&lt;/strong&gt;: A data URI such as &lt;code&gt;data:image/png;base64,&amp;lt;content&amp;gt;&lt;/code&gt; can be used. &lt;strong&gt;The current vLLM-Omni recipe limits each data-URI part to 1 MiB.&lt;/strong&gt; For larger reference images, use the &lt;code&gt;/v1/images/edits&lt;/code&gt; file-upload endpoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The generated image in the response is at &lt;code&gt;choices[0].message.content[0].image_url.url&lt;/code&gt;. For &lt;code&gt;/v1/images/generations&lt;/code&gt;, the image is at &lt;code&gt;data[0].b64_json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;/v1/images/generations&lt;/code&gt;, pass the resolution, number of steps, and guidance scale directly in the request body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8000/v1/images/generations &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;API_KEY&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "qwen-image-2.1",
    "prompt": "A corgi wearing a knitted beanie, sitting at a wooden table by the window, with a steaming cup of coffee nearby.",
    "size": "2048x2048",
    "num_inference_steps": 40,
    "true_cfg_scale": 1.0,
    "seed": 42
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpo248gbno0qrvkcnzse8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpo248gbno0qrvkcnzse8.png" alt="Generated corgi image" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Parameters to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;num_inference_steps&lt;/code&gt;&lt;/strong&gt;: Setting this to 40 is recommended. More steps usually increase generation time; results also depend on the prompt and sampling settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;seed&lt;/code&gt;&lt;/strong&gt;: Fix the seed when you need reproducible editing results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;true_cfg_scale&lt;/code&gt;&lt;/strong&gt;: This guide sets it to &lt;code&gt;1.0&lt;/code&gt;. Do not mix it up with &lt;code&gt;guidance_scale&lt;/code&gt;. If you also pass a negative prompt, consider how the guidance settings may affect latency and output quality.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2) Image editing and multi-image composition
&lt;/h3&gt;

&lt;p&gt;One of the important capabilities of 2.1 is that it can take reference images and reorganize a scene while attempting to preserve subjects' identities and product appearances. Typical scenarios showcased by the Qwen team include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Combining six portraits into a group photo&lt;/strong&gt;: Provide individual portraits and combine them into one group image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combining five fashion items into an outfit&lt;/strong&gt;: Provide a model, clothing, shoes, a bag, and a hat to generate a virtual try-on image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arranging a room from 10 furniture images&lt;/strong&gt;: Provide a furniture set and compose it into a complete interior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reference-image limits&lt;/strong&gt; depend on the inference backend. The model specification supports up to 10 images, while the current vLLM-Omni recipe allows up to 4 per request. Check whether your API and deployment version support local-editing controls such as selection, brush painting, and separate masks before relying on them.&lt;/p&gt;

&lt;p&gt;Here is an edit of the image generated above. Pass the reference image as an &lt;code&gt;image_url&lt;/code&gt; item to &lt;code&gt;/v1/chat/completions&lt;/code&gt; and ask the model to change only the specified content while preserving the rest of the composition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8000/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;API_KEY&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "qwen-image-2.1",
    "messages": [
      {
        "role": "user",
        "content": [
          {"type": "text", "text": "Replace the cup of coffee on the table in the reference image with a stack of books."},
          {"type": "image_url", "image_url": {"url": "data:image/png;base64,&amp;lt;IMG_B64&amp;gt;"}}
        ]
      }
    ],
    "modalities": ["image"],
    "extra_body": {
      "size": "1024x1024",
      "num_inference_steps": 40,
      "true_cfg_scale": 1.0,
      "seed": 42
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned image is at &lt;code&gt;choices[0].message.content[0].image_url.url&lt;/code&gt;. If the field contains a data URI, extract its Base64 content and decode it as &lt;code&gt;edited.png&lt;/code&gt;. For larger reference images, use the &lt;code&gt;/v1/images/edits&lt;/code&gt; file-upload endpoint to avoid the data-URI size limit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffh7o01mkc8btq4yaefkb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffh7o01mkc8btq4yaefkb.png" alt="Edited image with books replacing coffee" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Native transparent images
&lt;/h3&gt;

&lt;p&gt;The alpha channel is generated directly in latent space rather than added through post-processing. As a result, a PNG can be used in infographics, storyboards, stickers, and logos without first running a background-removal or segmentation model. The capability also works in reverse: you can extract a subject from a regular photo as a transparent layer, or edit text on a transparent layer while preserving the background.&lt;/p&gt;

&lt;p&gt;Pass an existing image as an &lt;code&gt;image_url&lt;/code&gt; item to &lt;code&gt;/v1/chat/completions&lt;/code&gt; and ask the model to extract the subject as a transparent layer. &lt;strong&gt;First confirm that the current service configuration outputs RGBA.&lt;/strong&gt; A model's ability to generate transparency does not mean every service configuration preserves the alpha channel by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:8000/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &amp;lt;API_KEY&amp;gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "qwen-image-2.1",
    "messages": [
      {
        "role": "user",
        "content": [
          {"type": "text", "text": "Extract the main subject from the reference image as a layer with a transparent background."},
          {"type": "image_url", "image_url": {"url": "data:image/png;base64,&amp;lt;IMG_B64&amp;gt;"}}
        ]
      }
    ],
    "modalities": ["image"],
    "extra_body": {
      "size": "1024x1024",
      "num_inference_steps": 40,
      "true_cfg_scale": 1.0,
      "seed": 42
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned image is at &lt;code&gt;choices[0].message.content[0].image_url.url&lt;/code&gt;. Decoding it should give you a PNG with an alpha channel; verify that the output file actually retains transparency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpciqmkucsjd9gx0ov7hy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpciqmkucsjd9gx0ov7hy.png" alt="Corgi isolated on a transparent background" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Important considerations
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The license is not Apache-2.0.&lt;/strong&gt; Qwen-Image-2.1 uses the Qwen Research License, which permits non-commercial research or evaluation. Commercial use requires a separate license. Consult the license text for the exact terms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Benchmark scores depend on the evaluation method.&lt;/strong&gt; When citing Qwen-Image-Bench, include the benchmark version, data date, and source. Note that the benchmark is published by the Qwen team; its results should not be presented as an independent third-party evaluation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Community reports are not universal conclusions.&lt;/strong&gt; Editing, multi-image composition, and transparent-image generation are capabilities highlighted by the project. Photorealism, artifacts, and consistency across multiple people can vary with the prompt, resolution, and inference configuration. When citing community feedback, include the source and test conditions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Notes for international readers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model hosting is region- and policy-dependent.&lt;/strong&gt; This guide uses a ModelScope repository ID. The Qwen project also publishes model resources through Hugging Face; choose an accessible source that complies with your organization's network and data policies. A China-based hosting platform should not be described as universally accessible or as the only option.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The hardware and system details are specific to the author's test environment.&lt;/strong&gt; The NVIDIA A800-SXM4-80GB, driver 570.172.08, and CUDA 12.8 are reproducibility details, not a universal hardware recommendation. Readers should check availability, export controls, and local deployment requirements in their region.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The license applies regardless of the deployment region.&lt;/strong&gt; Do not imply that using a hosted model or deploying it outside China changes the Qwen Research License's restrictions. Commercial use requires separate authorization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/QwenLM/Qwen-Image-2.1" rel="noopener noreferrer"&gt;Qwen-Image-2.1 official repository and model documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/QwenLM/Qwen-Image-2.1/blob/main/LICENSE" rel="noopener noreferrer"&gt;Qwen Research License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://recipes.vllm.ai/Qwen/Qwen-Image-2.1" rel="noopener noreferrer"&gt;vLLM Recipes: Qwen-Image-2.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vllm-project/vllm-omni/pull/7759" rel="noopener noreferrer"&gt;vLLM-Omni Qwen-Image-2.1 integration PR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Qwen-Image-2.1 has a clear design direction: reduce the previous generation's 20.4B-parameter DiT to 7B, bring text-to-image generation, image editing, and transparent-image generation into one checkpoint, and use Qwen3-VL to unify text and conditioning-image encoding. Block-Causal attention enables prefix KV reuse, reducing inference overhead in multi-image editing scenarios.&lt;/p&gt;

&lt;p&gt;With GPUStack's pluggable vLLM backend, you can configure a vLLM-Omni image that contains the Qwen-Image-2.1 integration, select the &lt;code&gt;Qwen/Qwen-Image-2.1&lt;/code&gt; repository, and verify that the startup command includes &lt;code&gt;--omni&lt;/code&gt;. &lt;strong&gt;The image must match the vLLM-Omni code version in use.&lt;/strong&gt; Check the official recipe for the supported parameters, input formats, and reference-image limits for your version.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Test environment: NVIDIA A800-SXM4-80GB | Driver: 570.172.08 | CUDA: 12.8 | GPUStack v2.2.2&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>github</category>
      <category>llm</category>
    </item>
    <item>
      <title>GPUStack Day 0 Support for Kimi-K3: vLLM vs. SGLang Inference Benchmark on 8 B300 GPUs</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Thu, 30 Jul 2026 10:44:17 +0000</pubDate>
      <link>https://dev.to/gpustack/gpustack-day-0-support-for-kimi-k3-vllm-vs-sglang-inference-benchmark-on-8xb300-gpus-2g0g</link>
      <guid>https://dev.to/gpustack/gpustack-day-0-support-for-kimi-k3-vllm-vs-sglang-inference-benchmark-on-8xb300-gpus-2g0g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article documents the deployment and benchmarking of Kimi-K3 on a single server equipped with 8×NVIDIA B300 GPUs. It compares vLLM and SGLang under 64K and 200K long-context workloads. The key finding is straightforward: &lt;strong&gt;vLLM is faster at 64K, while SGLang with DCP overtakes it at 200K. The difference comes primarily from KV access during Decode—not from Prefill.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kimi-K3 is a Mixture-of-Experts model designed for complex reasoning and long-context workloads. In this test, GPUStack was used to deploy the model on a single 8×NVIDIA B300 server with both vLLM and SGLang. Kimi-K3-DSpark was enabled as the draft model for speculative decoding.&lt;/p&gt;

&lt;p&gt;The most important results are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;64K input, concurrency 10:&lt;/strong&gt; vLLM completed the workload in 100.5 seconds versus 150.8 seconds for SGLang, making vLLM approximately 1.5× faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;200K input, concurrency 10:&lt;/strong&gt; SGLang completed the workload in 225.3 seconds versus 295.2 seconds for vLLM, making SGLang approximately 1.31× faster.&lt;/li&gt;
&lt;li&gt;From 64K to 200K, stable Decode throughput degraded by &lt;strong&gt;3.29×&lt;/strong&gt; on vLLM but only &lt;strong&gt;1.25×&lt;/strong&gt; on SGLang.&lt;/li&gt;
&lt;li&gt;The primary reason for the crossover is that SGLang ran with &lt;code&gt;--dcp-size=8&lt;/code&gt;, while vLLM used &lt;code&gt;decode_context_parallel_size=1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Prefill performance was broadly comparable; most of the gap appeared during Decode.&lt;/li&gt;
&lt;li&gt;The Random dataset produced extremely low DSPARK acceptance rates, so the speculative-decoding results should not be extrapolated directly to production traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; This was not a strictly controlled A/B test. The two engines differed in DCP, memory allocation, kernel backends, and acceptance criteria. The results are most useful for understanding bottlenecks and deployment trade-offs—not for declaring an absolute winner.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Test Environment
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;td&gt;Single node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU&lt;/td&gt;
&lt;td&gt;8×NVIDIA B300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visible memory per GPU&lt;/td&gt;
&lt;td&gt;267.69 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;Kimi-K3 (MXFP4)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Draft model&lt;/td&gt;
&lt;td&gt;Kimi-K3-DSpark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference engines&lt;/td&gt;
&lt;td&gt;vLLM / SGLang&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input lengths&lt;/td&gt;
&lt;td&gt;64K, 200K, and additional lengths&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output length&lt;/td&gt;
&lt;td&gt;3K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dataset&lt;/td&gt;
&lt;td&gt;Random&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Preparing the Model Weights
&lt;/h1&gt;

&lt;p&gt;Download the Kimi-K3 main model and DSpark draft models from ModelScope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kimi-K3 Main Model (MXFP4)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;modelscope download &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--model&lt;/span&gt; moonshotai/Kimi-K3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--local_dir&lt;/span&gt; ./Kimi-K3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  DSpark Draft Model for vLLM
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;modelscope download &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--model&lt;/span&gt; skyai/Kimi-K3-DSpark &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--local_dir&lt;/span&gt; ./Kimi-K3-DSpark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  DSpark Draft Model for SGLang
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;modelscope download &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--model&lt;/span&gt; skyai/sglang-Kimi-K3-DSpark &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--local_dir&lt;/span&gt; ./Kimi-K3-DSpark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Pulling the Inference Images
&lt;/h1&gt;

&lt;h2&gt;
  
  
  vLLM
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull vllm/vllm-openai:kimi-k3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SGLang
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull lmsysorg/sglang:kimi-k3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After pulling the images, add custom vLLM and SGLang versions under &lt;strong&gt;Inference Backends&lt;/strong&gt; in GPUStack.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deploying vLLM with GPUStack
&lt;/h1&gt;

&lt;p&gt;Create a custom vLLM backend in GPUStack, select the Kimi-K3 model and all eight B300 GPUs, and configure the required environment variables.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F061tclasoovi4q9j6n3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F061tclasoovi4q9j6n3d.png" width="800" height="963"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The vLLM custom backend and model settings are shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkkybwqv21ev7bkvldxv9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkkybwqv21ev7bkvldxv9.png" width="800" height="1701"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  vLLM Environment Variables
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;VLLM_ENABLE_K3_LATENT_MOE_TAIL_FUSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;VLLM_ALLREDUCE_USE_FLASHINFER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;VLLM_ENGINE_READY_TIMEOUT_S&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3600
&lt;span class="nv"&gt;VLLM_USE_V2_MODEL_RUNNER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="nv"&gt;VLLM_USE_RUST_FRONTEND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  vLLM Startup Parameters
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--trust-remote-code&lt;/span&gt;
&lt;span class="nt"&gt;--load-format&lt;/span&gt; fastsafetensors
&lt;span class="nt"&gt;--moe-backend&lt;/span&gt; auto
&lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.95
&lt;span class="nt"&gt;--tensor-parallel-size&lt;/span&gt; 8
&lt;span class="nt"&gt;--max-model-len&lt;/span&gt; 1000000
&lt;span class="nt"&gt;--kv-cache-dtype&lt;/span&gt; fp8
&lt;span class="nt"&gt;--attention-config&lt;/span&gt; &lt;span class="s1"&gt;'{"mla_prefill_backend":"TRTLLM_RAGGED","use_prefill_query_quantization":true}'&lt;/span&gt;
&lt;span class="nt"&gt;--max-num-batched-tokens&lt;/span&gt; 32768
&lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt;
&lt;span class="nt"&gt;--enable-auto-tool-choice&lt;/span&gt;
&lt;span class="nt"&gt;--tool-call-parser&lt;/span&gt; kimi_k3
&lt;span class="nt"&gt;--reasoning-parser&lt;/span&gt; kimi_k3
&lt;span class="nt"&gt;--max-num-seqs&lt;/span&gt; 32
&lt;span class="nt"&gt;--speculative-config&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"Inferact/Kimi-K3-DSpark","num_speculative_tokens":7,"method":"dspark","attention_backend":"FLASHINFER_MLA","draft_sample_method":"probabilistic","rejection_sample_method":"block"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In this test, &lt;code&gt;--gpu-memory-utilization 0.95&lt;/code&gt; overcommitted the KV pool and caused runtime OOM retries. A safer configuration is discussed later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Deploying SGLang with GPUStack
&lt;/h1&gt;

&lt;p&gt;Create an SGLang custom backend, select all eight B300 GPUs, and configure the model and startup parameters.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyd27mh8rqo6lmslxajwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyd27mh8rqo6lmslxajwk.png" width="800" height="1307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The SGLang custom backend and model settings are shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvfmt9r6csk760z72kff8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvfmt9r6csk760z72kff8.png" width="800" height="1633"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SGLang Startup Parameters
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--trust-remote-code&lt;/span&gt;
&lt;span class="nt"&gt;--model-path&lt;/span&gt; &amp;lt;Kimi-K3 model path&amp;gt;
&lt;span class="nt"&gt;--tp-size&lt;/span&gt; 8
&lt;span class="nt"&gt;--dcp-size&lt;/span&gt; 8
&lt;span class="nt"&gt;--disable-custom-all-reduce&lt;/span&gt;
&lt;span class="nt"&gt;--enable-symm-mem&lt;/span&gt;
&lt;span class="nt"&gt;--mem-fraction-static&lt;/span&gt; 0.85
&lt;span class="nt"&gt;--reasoning-parser&lt;/span&gt; kimi_k3
&lt;span class="nt"&gt;--tool-call-parser&lt;/span&gt; kimi_k3
&lt;span class="nt"&gt;--mamba-full-memory-ratio&lt;/span&gt; 0.86
&lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0
&lt;span class="nt"&gt;--port&lt;/span&gt; 30000
&lt;span class="nt"&gt;--speculative-algorithm&lt;/span&gt; DSPARK
&lt;span class="nt"&gt;--speculative-draft-model-path&lt;/span&gt; &amp;lt;Kimi-K3-DSpark model path&amp;gt;
&lt;span class="nt"&gt;--speculative-dspark-block-size&lt;/span&gt; 7
&lt;span class="nt"&gt;--enable-linear-replayssm-spec&lt;/span&gt;
&lt;span class="nt"&gt;--chunked-prefill-size&lt;/span&gt; 32768
&lt;span class="nt"&gt;--max-prefill-tokens&lt;/span&gt; 32768
&lt;span class="nt"&gt;--context-length&lt;/span&gt; 1000000
&lt;span class="nt"&gt;--kv-cache-dtype&lt;/span&gt; fp8_e4m3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GPUStack exposes the live service logs, throughput, and KV Cache state after the service starts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuuwvt2su74v0p143gk0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuuwvt2su74v0p143gk0y.png" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  64K / 3K at Concurrency 10
&lt;/h1&gt;

&lt;p&gt;The first comparison used 64K input, 3K output, and ten concurrent requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  vLLM Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ipnd2lympot3umiyqjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ipnd2lympot3umiyqjj.png" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SGLang Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwgiv625td7bemyu7561i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwgiv625td7bemyu7561i.png" width="800" height="312"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The corresponding inference logs are shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1mia1edoj57wb9a6gq1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1mia1edoj57wb9a6gq1.png" width="799" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdfjwt65a5gesuzg35yqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdfjwt65a5gesuzg35yqu.png" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Results Across Different Input Lengths
&lt;/h1&gt;

&lt;p&gt;Additional input lengths were tested to observe how context growth affects TTFT, TPOT, ITL, and end-to-end latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  vLLM
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywmm2iucevzideim0pcm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fywmm2iucevzideim0pcm.png" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SGLang
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7r5kjyz0no40lexz2jwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7r5kjyz0no40lexz2jwx.png" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Core Result: Performance Crosses Over Between 64K and 200K
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;vLLM&lt;/th&gt;
&lt;th&gt;SGLang&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;64K end-to-end time&lt;/td&gt;
&lt;td&gt;100.5 s&lt;/td&gt;
&lt;td&gt;150.8 s&lt;/td&gt;
&lt;td&gt;vLLM leads by ~1.5×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200K end-to-end time&lt;/td&gt;
&lt;td&gt;295.2 s&lt;/td&gt;
&lt;td&gt;225.3 s&lt;/td&gt;
&lt;td&gt;SGLang leads by ~1.31×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;64K stable Decode throughput&lt;/td&gt;
&lt;td&gt;~501 tok/s&lt;/td&gt;
&lt;td&gt;~335 tok/s&lt;/td&gt;
&lt;td&gt;vLLM leads by ~1.5×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200K stable Decode throughput&lt;/td&gt;
&lt;td&gt;~163 tok/s&lt;/td&gt;
&lt;td&gt;~268 tok/s&lt;/td&gt;
&lt;td&gt;SGLang leads by ~1.64×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decode degradation, 64K→200K&lt;/td&gt;
&lt;td&gt;3.29×&lt;/td&gt;
&lt;td&gt;1.25×&lt;/td&gt;
&lt;td&gt;SGLang scales better&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In one sentence:&lt;/strong&gt; vLLM is faster at shorter contexts because it avoids DCP communication overhead. As context grows, KV bandwidth becomes dominant, and SGLang’s DCP=8 distributes the KV reads across eight GPUs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Source inspection shows that this is not simply a missing vLLM flag. vLLM explicitly prohibits DCP and DSPARK from being enabled together. SGLang allows them to coexist, but speculative decoding falls back to a non-adaptive verification mode. This is an architectural trade-off rather than a configuration oversight.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why the Crossover Happens
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Decode Scalability Is the Decisive Factor
&lt;/h2&gt;

&lt;p&gt;Stable throughput was measured after all ten requests entered Decode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwv0k0g6hg1cremu50mzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwv0k0g6hg1cremu50mzw.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Aggregate Decode throughput during the stable ten-request phase, in tokens/s, based on engine-reported logs.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vLLM (DCP=1)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At 64K, stable throughput was approximately 439–537 tok/s, peaking at 537 tok/s.&lt;/li&gt;
&lt;li&gt;Per request, this is approximately 53.7 tok/s, or 18.6 ms/token.&lt;/li&gt;
&lt;li&gt;At 200K, stable throughput was approximately 157.8–166.6 tok/s, averaging about 163 tok/s.&lt;/li&gt;
&lt;li&gt;Per request, this is approximately 16.3 tok/s, or 61.3 ms/token.&lt;/li&gt;
&lt;li&gt;Context length increased by about 3.1× while Decode performance fell by 3.29×, indicating near-linear degradation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;SGLang (DCP=8)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At 64K, stable throughput was approximately 313–418 tok/s, averaging about 335 tok/s.&lt;/li&gt;
&lt;li&gt;Per request, this is approximately 33.5 tok/s, or 29.9 ms/token.&lt;/li&gt;
&lt;li&gt;At 200K, stable throughput was approximately 252–288 tok/s, averaging about 268 tok/s.&lt;/li&gt;
&lt;li&gt;Per request, this is approximately 26.8 tok/s, or 37.3 ms/token.&lt;/li&gt;
&lt;li&gt;Context length increased by about 3.1× while Decode performance fell by only 1.25×.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At 64K, DCP communication overhead is greater than the reduction in KV reads, so vLLM is faster. At 200K, KV bandwidth becomes the primary bottleneck and SGLang’s DCP advantage becomes visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Prefill Performance Is Broadly Comparable
&lt;/h2&gt;

&lt;p&gt;Both engines used a 32,768-token Prefill budget. Stable aggregate Prefill throughput was approximately &lt;strong&gt;19K–23K tok/s&lt;/strong&gt;, indicating comparable MoE + MLA Prefill capability on 8×B300.&lt;/p&gt;

&lt;p&gt;The vLLM 64K run was affected by 32 soft OOM retries across eight GPUs and runtime JIT compilation of four kernels. These events occurred early in the test and made vLLM’s first-batch TTFT look worse. They were not reproduced in the 200K run, and SGLang did not report matching OOM or JIT events.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. SGLang Logs Expose Long-Context Prefill Degradation
&lt;/h2&gt;

&lt;p&gt;For a single 200K request, SGLang reported the following throughput over six chunks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;22265 → 21064 → 19628 → 18475 → 17243 → 16408 tok/s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Throughput returned to approximately 22K tok/s when the next request started. This directly shows the rising attention cost as cached context grows. vLLM reports a coarser ten-second aggregate prompt throughput, so the same pattern is less visible in its logs.&lt;/p&gt;

&lt;h1&gt;
  
  
  DSPARK Speculative Decoding Added Little Value
&lt;/h1&gt;

&lt;p&gt;The Random dataset is effectively unpredictable, making it difficult for the draft model to produce consecutive accepted tokens. Both engines used Kimi-K3-DSpark with seven speculative tokens, but average accepted length at 200K remained close to one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vLLM: approximately 1.05–1.17&lt;/li&gt;
&lt;li&gt;SGLang: approximately 1.05–1.17&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the vLLM 200K run, drafted throughput was about 990 tok/s while accepted throughput was only about 21 tok/s. Approximately &lt;strong&gt;98% of draft-model computation was discarded&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Accepted Length&lt;/th&gt;
&lt;th&gt;Acceptance / Draft Hit Rate&lt;/th&gt;
&lt;th&gt;Interpretation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;64K&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;2.27–2.51&lt;/td&gt;
&lt;td&gt;18%–21%&lt;/td&gt;
&lt;td&gt;The only range with material benefit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;64K&lt;/td&gt;
&lt;td&gt;SGLang&lt;/td&gt;
&lt;td&gt;1.21–1.55&lt;/td&gt;
&lt;td&gt;3%–8%&lt;/td&gt;
&lt;td&gt;Much weaker than vLLM on the same data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200K&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;1.05–1.17&lt;/td&gt;
&lt;td&gt;1.1%–2.5%&lt;/td&gt;
&lt;td&gt;Draft compute is almost entirely wasted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;200K&lt;/td&gt;
&lt;td&gt;SGLang&lt;/td&gt;
&lt;td&gt;1.05–1.17&lt;/td&gt;
&lt;td&gt;1%–2%&lt;/td&gt;
&lt;td&gt;The same collapse occurs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;This run measured a “speculation as pure overhead” scenario. Production validation should use ShareGPT, real business prompts, or another natural-language dataset.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Different Acceptance Criteria
&lt;/h2&gt;

&lt;p&gt;vLLM used probabilistic draft sampling with block rejection, while the SGLang DSPARK path used strict greedy matching. In SGLang, a mismatch on the first token invalidates the remaining tokens in the block. Strict comparison therefore requires the same dataset, sampling settings, gamma, and acceptance criteria.&lt;/p&gt;

&lt;h1&gt;
  
  
  Client Metrics: Excluding Unreliable Throughput Columns
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;vLLM 64K&lt;/th&gt;
&lt;th&gt;SGLang 64K&lt;/th&gt;
&lt;th&gt;vLLM 200K&lt;/th&gt;
&lt;th&gt;SGLang 200K&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Total time (s)&lt;/td&gt;
&lt;td&gt;100.5&lt;/td&gt;
&lt;td&gt;150.82&lt;/td&gt;
&lt;td&gt;295.21&lt;/td&gt;
&lt;td&gt;225.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean request latency (s)&lt;/td&gt;
&lt;td&gt;84.42&lt;/td&gt;
&lt;td&gt;141.53&lt;/td&gt;
&lt;td&gt;284.58&lt;/td&gt;
&lt;td&gt;217.83&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean TTFT (ms)&lt;/td&gt;
&lt;td&gt;34,838.8&lt;/td&gt;
&lt;td&gt;41,670.6&lt;/td&gt;
&lt;td&gt;125,210.8&lt;/td&gt;
&lt;td&gt;59,002.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TTFT P50 (ms)&lt;/td&gt;
&lt;td&gt;34,181.1&lt;/td&gt;
&lt;td&gt;40,391.9&lt;/td&gt;
&lt;td&gt;125,189.2&lt;/td&gt;
&lt;td&gt;54,104.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TTFT P90 (ms)&lt;/td&gt;
&lt;td&gt;36,987.9&lt;/td&gt;
&lt;td&gt;53,525.0&lt;/td&gt;
&lt;td&gt;126,667.0&lt;/td&gt;
&lt;td&gt;103,336.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean TPOT (ms)&lt;/td&gt;
&lt;td&gt;12.28&lt;/td&gt;
&lt;td&gt;47.18&lt;/td&gt;
&lt;td&gt;45.21&lt;/td&gt;
&lt;td&gt;72.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mean ITL (ms)&lt;/td&gt;
&lt;td&gt;9.94&lt;/td&gt;
&lt;td&gt;33.3&lt;/td&gt;
&lt;td&gt;3.47&lt;/td&gt;
&lt;td&gt;52.96&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failed / incomplete&lt;/td&gt;
&lt;td&gt;0 / 0&lt;/td&gt;
&lt;td&gt;0 / 0&lt;/td&gt;
&lt;td&gt;0 / 0&lt;/td&gt;
&lt;td&gt;0 / 0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Some client-reported throughput fields cannot be reconciled with token counts, concurrency, and elapsed time. For example, the vLLM 200K run reported 1111.61 output tok/s, while &lt;code&gt;10 × 3000 ÷ 295.21&lt;/code&gt; gives a physical upper bound of about 101.6 tok/s. The discrepancy is consistently close to 11×, so this article uses latency metrics from the client and throughput from engine logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  TTFT Semantics Must Also Be Aligned
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;--reasoning-parser kimi_k3&lt;/code&gt;, reasoning output is emitted in &lt;code&gt;delta.reasoning&lt;/code&gt;, not &lt;code&gt;delta.content&lt;/code&gt;. A benchmark that starts TTFT only at the first content token systematically inflates TTFT for both engines. For reasoning models, a better definition is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;time-to-first-any-delta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The timer should stop on the first reasoning or content delta.&lt;/p&gt;

&lt;h1&gt;
  
  
  Memory Allocation and KV Cache Capacity
&lt;/h1&gt;

&lt;p&gt;Each B300 exposed 267.69 GiB. Model weight memory was similar, but the remaining memory was allocated differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  vLLM
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model weights and non-torch memory&lt;/td&gt;
&lt;td&gt;197.72 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Peak activation memory&lt;/td&gt;
&lt;td&gt;12.82 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CUDA Graph&lt;/td&gt;
&lt;td&gt;5.13 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV Cache&lt;/td&gt;
&lt;td&gt;43.76 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The KV pool held 2,687,776 tokens, giving a theoretical maximum concurrency of 2.69 at a 1M context. However, the pool was overcommitted. vLLM logs indicated that 38.48 GiB was the safe KV allocation under the configured budget.&lt;/p&gt;

&lt;p&gt;Use either:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.92
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--kv-cache-memory&lt;/span&gt; 41317885440
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  SGLang
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model weights&lt;/td&gt;
&lt;td&gt;195.86 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full-attention KV Cache&lt;/td&gt;
&lt;td&gt;11.80 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Draft-model KV (K–V)&lt;/td&gt;
&lt;td&gt;8.74 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mamba / SSM state&lt;/td&gt;
&lt;td&gt;10.93 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remaining space&lt;/td&gt;
&lt;td&gt;17.08 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The full-attention pool held 916,672 tokens, below the configured one-million-token context. A full 1M request therefore cannot fit without adjusting the pool. &lt;code&gt;max_running_requests&lt;/code&gt; also fell from 48 to 39 because of the Mamba state cache.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cold-Start Cost
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stage&lt;/th&gt;
&lt;th&gt;vLLM&lt;/th&gt;
&lt;th&gt;SGLang&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Container created&lt;/td&gt;
&lt;td&gt;17:06:21&lt;/td&gt;
&lt;td&gt;18:01:45&lt;/td&gt;
&lt;td&gt;GPUStack timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weight loading&lt;/td&gt;
&lt;td&gt;163.8 s&lt;/td&gt;
&lt;td&gt;141.0 s&lt;/td&gt;
&lt;td&gt;12 vs. 96 shards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weight size per GPU&lt;/td&gt;
&lt;td&gt;194.54 GiB&lt;/td&gt;
&lt;td&gt;195.86 GB&lt;/td&gt;
&lt;td&gt;MXFP4 MoE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kernel warmup&lt;/td&gt;
&lt;td&gt;CuTeDSL + KDA Triton&lt;/td&gt;
&lt;td&gt;KDA / FA4 / RoPE&lt;/td&gt;
&lt;td&gt;K3-specific JIT on both&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CUDA Graph capture&lt;/td&gt;
&lt;td&gt;85–88 s, 51 sizes&lt;/td&gt;
&lt;td&gt;~5.5 min, 67 sizes&lt;/td&gt;
&lt;td&gt;SGLang captured more shapes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Engine initialization&lt;/td&gt;
&lt;td&gt;409.61 s&lt;/td&gt;
&lt;td&gt;~370 s&lt;/td&gt;
&lt;td&gt;SGLang inferred from timestamps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container-to-ready&lt;/td&gt;
&lt;td&gt;~10.6 min&lt;/td&gt;
&lt;td&gt;~10.2 min&lt;/td&gt;
&lt;td&gt;Same order of magnitude&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both engines required roughly ten minutes. Frequent autoscaling should therefore use warm instances, staged expansion, or prewarming.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Configurations Were Not Fully Equivalent
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;vLLM&lt;/th&gt;
&lt;th&gt;SGLang&lt;/th&gt;
&lt;th&gt;Potential Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Decode context parallelism&lt;/td&gt;
&lt;td&gt;DCP=1&lt;/td&gt;
&lt;td&gt;DCP=8, &lt;code&gt;comm=a2a&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Dominant at long context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;All-Reduce&lt;/td&gt;
&lt;td&gt;FlashInfer + Custom + SymmMem&lt;/td&gt;
&lt;td&gt;Custom AR disabled; NCCL fallback&lt;/td&gt;
&lt;td&gt;High for small-batch Decode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MLA Prefill backend&lt;/td&gt;
&lt;td&gt;TRTLLM_RAGGED&lt;/td&gt;
&lt;td&gt;&lt;code&gt;trtllm_mla&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MLA Decode backend&lt;/td&gt;
&lt;td&gt;FLASHINFER_MLA&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cutedsl_mla&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linear attention&lt;/td&gt;
&lt;td&gt;FlashKDA Prefill&lt;/td&gt;
&lt;td&gt;Triton Decode/verify/extend&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MoE backend&lt;/td&gt;
&lt;td&gt;FLASHINFER_TRTLLM_MXFP4_MXFP8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;flashinfer_mxfp4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KV page size&lt;/td&gt;
&lt;td&gt;32, aligned to 1536&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compile path&lt;/td&gt;
&lt;td&gt;Disabled by breakable CUDA Graph&lt;/td&gt;
&lt;td&gt;Not enabled&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory fraction&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;Low–medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrency limit&lt;/td&gt;
&lt;td&gt;&lt;code&gt;max_num_seqs=64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;48→39&lt;/td&gt;
&lt;td&gt;Not reached in this test&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Warnings Worth Addressing
&lt;/h1&gt;

&lt;h2&gt;
  
  
  FP8 KV Cache Scaling Factors
&lt;/h2&gt;

&lt;p&gt;Both engines ran FP8 KV Cache with a fallback scale of 1.0. Performance conclusions should be paired with a fixed quality evaluation to confirm that FP8 KV Cache does not introduce unacceptable accuracy loss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Slow Tokenizer
&lt;/h2&gt;

&lt;p&gt;Both engines reported a slow tokenizer. At 64K and 200K, tokenization time contributes directly to TTFT. A fast tokenizer should be enabled where possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  SGLang Device Identification
&lt;/h2&gt;

&lt;p&gt;One log entry identified the device as &lt;code&gt;NVIDIA L20D&lt;/code&gt;, while other entries correctly reported B300/GB300 and SM100/SM103. Because DCP communication backend selection can depend on the device name, the selected &lt;code&gt;a2a&lt;/code&gt; path should be verified.&lt;/p&gt;

&lt;h2&gt;
  
  
  vLLM Memory Utilization
&lt;/h2&gt;

&lt;p&gt;The 0.95 setting overcommitted KV memory. Reducing it to 0.92 or explicitly setting the log-recommended KV cache size removes the repeated runtime allocation retries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Potentially Inactive vLLM Fusions
&lt;/h2&gt;

&lt;p&gt;Some reported fusions are Inductor passes. Kimi-K3 enables breakable CUDA Graph mode, which can force compilation mode to &lt;code&gt;NONE&lt;/code&gt;; the fusions may therefore not have been applied. FlashInfer autotuning was also disabled, meaning this vLLM result may be below its best achievable performance.&lt;/p&gt;

&lt;h1&gt;
  
  
  Source-Level Root Cause: DCP vs. Speculative Decoding
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;This is the strongest conclusion in the analysis, and it cannot be bypassed with a simple flag change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;vLLM structurally disallows DCP and DSPARK from running together. When &lt;code&gt;decode_context_parallel_size &amp;gt; 1&lt;/code&gt; is combined with &lt;code&gt;K3DSparkModel&lt;/code&gt;, startup fails. To gain long-context KV sharding in vLLM, speculative decoding must be disabled.&lt;/p&gt;

&lt;p&gt;SGLang permits DCP and DSPARK together, but &lt;code&gt;dcp_size &amp;gt; 1&lt;/code&gt; forces static ragged verification. Adaptive SPS cost tables, STS calibration, confidence planning, and block acceptance estimation are no longer active.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;vLLM&lt;/th&gt;
&lt;th&gt;SGLang&lt;/th&gt;
&lt;th&gt;Deployment Implication&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DCP + speculative decoding&lt;/td&gt;
&lt;td&gt;Not allowed&lt;/td&gt;
&lt;td&gt;Allowed, but non-adaptive&lt;/td&gt;
&lt;td&gt;Both require a trade-off&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-context KV sharding&lt;/td&gt;
&lt;td&gt;Requires disabling speculation&lt;/td&gt;
&lt;td&gt;Can coexist with speculation&lt;/td&gt;
&lt;td&gt;Structural source of the 200K advantage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adaptive speculation&lt;/td&gt;
&lt;td&gt;No equivalent planner&lt;/td&gt;
&lt;td&gt;Disabled when DCP is enabled&lt;/td&gt;
&lt;td&gt;Neither offers both benefits together&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adjustable acceptance&lt;/td&gt;
&lt;td&gt;Two explicit parameters&lt;/td&gt;
&lt;td&gt;Threshold hard-coded in kernel&lt;/td&gt;
&lt;td&gt;SGLang has no ready tuning knob&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Additional Findings from Source Inspection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SGLang’s Fused KDA Verify Kernel Probably Did Not Run
&lt;/h3&gt;

&lt;p&gt;The dispatcher assigns the verify kernel to Triton unless strict runtime shape constraints allow the CuTe path. Logs ended with &lt;code&gt;verify=TritonKDAKernel&lt;/code&gt;, leaving additional optimization potential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identity of SGLang’s “Second KV Pool”
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;7,333,376 = 916,672 × 8&lt;/code&gt;, exactly matching &lt;code&gt;dcp_size&lt;/code&gt;. The pool is the draft worker’s MHA KV pool addressed in DCP’s virtual token space, not a second architectural KV type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why vLLM Uses a 1536-Token Attention Block
&lt;/h3&gt;

&lt;p&gt;The hybrid model requires an attention page to be at least as large as a Mamba page. The block grows from 32 to 1536, with approximately 0.70% Mamba-page padding. This coarser boundary also influences chunk alignment and can contribute to Decode starvation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Source of vLLM’s 2.69× Concurrency Limit
&lt;/h3&gt;

&lt;p&gt;The scheduler reserves KV for the full maximum sequence length at admission time. Reducing &lt;code&gt;--max-model-len&lt;/code&gt; from 1M to the actual production requirement immediately increases concurrency.&lt;/p&gt;

&lt;h1&gt;
  
  
  Deployment Recommendations
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Inputs Up to 64K, Throughput First
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prefer vLLM.&lt;/strong&gt; It delivered approximately 1.5× higher Decode throughput and approximately 1.5× lower end-to-end time in this test.&lt;/p&gt;

&lt;h2&gt;
  
  
  200K and Longer Document Workloads
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prefer SGLang with DCP.&lt;/strong&gt; It delivered approximately 1.64× higher Decode throughput at 200K and degraded much more slowly as context increased. Increase the KV pool to at least the target context length before production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Long Context Plus High Concurrency
&lt;/h2&gt;

&lt;p&gt;The current configuration favors vLLM’s capacity, but this conclusion requires retesting. SGLang should first rebalance KV and Mamba memory, then be compared with a vLLM configuration that disables speculation and enables DCP.&lt;/p&gt;

&lt;h1&gt;
  
  
  Next-Round Retest Plan
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;th&gt;Rationale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Set &lt;code&gt;--long-prefill-token-threshold 4096&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;Prevent one long Prefill from consuming the entire Decode budget&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Replace Random with ShareGPT or real long documents&lt;/td&gt;
&lt;td&gt;Benchmark platform&lt;/td&gt;
&lt;td&gt;Current acceptance is only 1%–8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Measure time-to-first-any-delta&lt;/td&gt;
&lt;td&gt;Benchmark platform&lt;/td&gt;
&lt;td&gt;Include reasoning deltas in TTFT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Fix throughput accounting&lt;/td&gt;
&lt;td&gt;Benchmark platform&lt;/td&gt;
&lt;td&gt;Current vLLM output throughput is inflated by ~11×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Reduce memory utilization to 0.92 or pin KV memory&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;Remove runtime OOM retries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Add an SGLang DCP-off group&lt;/td&gt;
&lt;td&gt;SGLang&lt;/td&gt;
&lt;td&gt;Isolate DCP and static-verification effects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Set max model length to the business requirement&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;Avoid unnecessary full-length KV reservation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Expand warmup to cover runtime JIT shapes&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;Remove first-batch compilation noise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Re-enable FlashInfer autotuning&lt;/td&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;Allow better MoE tactics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Re-enable custom All-Reduce and diagnose multicast&lt;/td&gt;
&lt;td&gt;SGLang&lt;/td&gt;
&lt;td&gt;Reduce small-batch communication overhead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Diagnose the KDA CuTe verify fallback&lt;/td&gt;
&lt;td&gt;SGLang&lt;/td&gt;
&lt;td&gt;Recover unused optimization potential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Provide FP8 KV scaling factors and run quality regression&lt;/td&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;td&gt;Add an accuracy basis to performance conclusions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Increase Mamba memory ratio or use bf16 SSM&lt;/td&gt;
&lt;td&gt;SGLang&lt;/td&gt;
&lt;td&gt;Remove the 39-request limit and raise the KV pool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Add P99 and concurrency ≥64&lt;/td&gt;
&lt;td&gt;Benchmark platform&lt;/td&gt;
&lt;td&gt;Exercise scheduler and concurrency limits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The most valuable result of this 8×B300 test is not a simple ranking. It shows how the bottleneck changes with context length:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At 64K, communication overhead matters more, favoring vLLM.&lt;/li&gt;
&lt;li&gt;At 200K, KV read bandwidth dominates, allowing SGLang with DCP to overtake.&lt;/li&gt;
&lt;li&gt;Prefill is not the main differentiator; Decode scalability is.&lt;/li&gt;
&lt;li&gt;Speculative decoding is ineffective on Random data.&lt;/li&gt;
&lt;li&gt;Memory allocation, TTFT semantics, and client-side throughput accounting can materially change the apparent result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Production selection should therefore evaluate &lt;strong&gt;context length, concurrency, KV capacity, DCP, real request distributions, and output quality&lt;/strong&gt; together—not rely on a single TPS number.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
      <category>github</category>
    </item>
    <item>
      <title>Day 0 Deployment of GLM-5.2-FP8-DSpark on GPUStack</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Wed, 22 Jul 2026 10:28:37 +0000</pubDate>
      <link>https://dev.to/gpustack/day-0-deployment-of-glm-52-fp8-dspark-on-gpustack-oh</link>
      <guid>https://dev.to/gpustack/day-0-deployment-of-glm-52-fp8-dspark-on-gpustack-oh</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is curated from a real-world deployment experience shared by a GPUStack community member. GLM-5.2-FP8-DSpark is an enhanced version of GLM-5.2-FP8 that applies &lt;strong&gt;Speculative Decoding&lt;/strong&gt; by loading an external draft model (Speculator) provided by Red Hat AI. It keeps the original model weights unchanged while adding an additional draft model to improve decoding throughput. On the day the model was released (Day 0), a community member deployed it on an &lt;strong&gt;8× H20-141G&lt;/strong&gt; environment through GPUStack and conducted a performance comparison against the original GLM-5.2-FP8 under the same hardware conditions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's start with the conclusion. The results from this test are mixed and should be interpreted objectively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-concurrency scenario:&lt;/strong&gt; In the GPUStack Playground, DSpark achieved approximately &lt;strong&gt;171 TPS&lt;/strong&gt;, while the original GLM-5.2-FP8 achieved approximately &lt;strong&gt;72 TPS&lt;/strong&gt;, delivering around a &lt;strong&gt;2.2× improvement&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-concurrency scenario (64K input / 3K output):&lt;/strong&gt; DSpark achieved &lt;strong&gt;59.8 TPS&lt;/strong&gt; output throughput, which was actually &lt;strong&gt;lower&lt;/strong&gt; than the &lt;strong&gt;99.2 TPS&lt;/strong&gt; achieved by the original MTP approach. Due to the lower acceptance rate of the external draft model on the Random dataset, DSpark did not improve performance under high concurrency and even introduced regression.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key takeaway:&lt;/strong&gt; With the specific external draft model + GLM-5.2-FP8 combination tested in this article, DSpark is currently better suited for &lt;strong&gt;single-concurrency / low-concurrency interactive scenarios where first-token latency and response throughput are critical&lt;/strong&gt;, or for &lt;strong&gt;research and evaluation purposes&lt;/strong&gt;. For high-concurrency production workloads, waiting for draft models with higher acceptance rates is recommended.
&lt;em&gt;(The conclusions above only apply to the draft model and dataset used in this test, and do not represent the upper limit of the DSpark speculative decoding approach.)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following sections provide the complete deployment process and benchmark results.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Deploying GLM-5.2-FP8-DSpark on GPUStack
&lt;/h2&gt;

&lt;p&gt;DSpark requires a newer vLLM image (&lt;strong&gt;v0.25.0&lt;/strong&gt;) to support speculative decoding with an external draft model. With GPUStack's pluggable vLLM backend architecture, we only need to add a new vLLM backend version. The entire process can be completed through the GPUStack Web UI with just a few clicks.&lt;/p&gt;

&lt;h3&gt;
  
  
  ① Add a New vLLM Backend Version
&lt;/h3&gt;

&lt;p&gt;From the left navigation menu, go to &lt;strong&gt;Inference Backend&lt;/strong&gt;, find the &lt;strong&gt;vLLM&lt;/strong&gt; card, and click &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Under &lt;strong&gt;Version Configuration&lt;/strong&gt;, click &lt;strong&gt;Add Version&lt;/strong&gt; and create a new version named &lt;code&gt;25&lt;/code&gt;. Enter the following image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm/vllm-openai:v0.25.0、
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;CUDA&lt;/strong&gt; as the framework and save the configuration. A new backend version named &lt;code&gt;25-custom&lt;/code&gt; will then become available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frj31vvahaug7fuap5s39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frj31vvahaug7fuap5s39.png" alt="Add vLLM v0.25.0 Version" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ② Create a Deployment and Select Model &amp;amp; Backend
&lt;/h3&gt;

&lt;p&gt;Go back to the &lt;strong&gt;Deployments&lt;/strong&gt; page and click &lt;strong&gt;Deploy Model&lt;/strong&gt; in the upper-right corner. Configure the basic information as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source: Select &lt;strong&gt;ModelScope&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Repository ID: &lt;code&gt;ZhipuAI/GLM-5.2-FP8&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Backend: Select &lt;strong&gt;vLLM&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Backend Version: Select the newly added &lt;strong&gt;25-custom&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl3vh47ie1oy66vsussoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl3vh47ie1oy66vsussoq.png" alt="Select Model Source and Backend Version" width="799" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ③ Configure Backend Parameters
&lt;/h3&gt;

&lt;p&gt;In the &lt;strong&gt;Advanced&lt;/strong&gt; section, configure the backend parameters as follows (using an 8× H20-141G environment as an example):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
--max-model-len 131072&lt;br&gt;
--tensor-parallel-size 8&lt;br&gt;
--tool-call-parser glm47&lt;br&gt;
--enable-auto-tool-choice&lt;br&gt;
--reasoning-parser glm45&lt;br&gt;
--enable-expert-parallel&lt;br&gt;
--trust-remote-code&lt;br&gt;
--gpu-memory-utilization=0.9&lt;br&gt;
--max-num-batched-tokens 32768&lt;br&gt;
--max-num-seqs 16&lt;br&gt;
--speculative-config '{"model":"/var/lib/gpustack/cache/model_scope/RedHatAI/GLM-5.2-speculator.dspark","num_speculative_tokens":7,"method":"dspark"}'&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The key parameter is &lt;code&gt;--speculative-config&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;method&lt;/code&gt; to &lt;code&gt;dspark&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;model&lt;/code&gt; to the downloaded external draft model path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the engine takes longer to load, add the environment variable:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
VLLM_ENGINE_READY_TIMEOUT_S=3600&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;to extend the ready timeout.&lt;br&gt;
https://&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftf57qd34zlpp6pr4fenf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftf57qd34zlpp6pr4fenf.png" alt="Configure vLLM Backend Parameters" width="800" height="1222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Draft model download:&lt;br&gt;
&lt;a href="https://modelscope.cn/models/RedHatAI/GLM-5.2-speculator.dspark" rel="noopener noreferrer"&gt;https://modelscope.cn/models/RedHatAI/GLM-5.2-speculator.dspark&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Submit the deployment. Once the instance status changes to &lt;strong&gt;Running&lt;/strong&gt;, the deployment is complete.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Performance Benchmark: DSpark vs Original GLM-5.2-FP8
&lt;/h2&gt;

&lt;p&gt;Under the &lt;strong&gt;same hardware environment (8× H20-141G)&lt;/strong&gt;, we compared the two models from two perspectives: &lt;strong&gt;single-concurrency interactive inference&lt;/strong&gt; and &lt;strong&gt;high-concurrency batch inference&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 1: Single-Concurrency Interactive Inference
&lt;/h3&gt;

&lt;p&gt;Run a conversation directly in the GPUStack Playground and monitor the real-time output throughput.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GLM-5.2-FP8-DSpark:&lt;/strong&gt;&lt;br&gt;
Output throughput reached &lt;strong&gt;171.6 Tokens/s&lt;/strong&gt;, remaining stable in the 170+ range.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Original GLM-5.2-FP8:&lt;/strong&gt;&lt;br&gt;
Output throughput reached &lt;strong&gt;71.81 Tokens/s&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Under single-concurrency workloads, DSpark achieved approximately &lt;strong&gt;171 TPS&lt;/strong&gt;, around &lt;strong&gt;2.2× faster&lt;/strong&gt; than the original version (~72 TPS). This demonstrates the typical benefit of speculative decoding in low-concurrency interactive scenarios.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Scenario 2: High-Concurrency Batch Inference (64K Input / 3K Output, 10 Requests)
&lt;/h3&gt;

&lt;p&gt;Using GPUStack's built-in benchmark tool, we tested the model with a Random dataset containing &lt;strong&gt;64K input tokens / 3K output tokens&lt;/strong&gt; and &lt;strong&gt;10 requests&lt;/strong&gt; (with an actual average concurrency of approximately 6).&lt;/p&gt;

&lt;p&gt;The baseline for comparison is the original MTP approach with speculative decoding enabled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Original MTP (&lt;code&gt;method: mtp&lt;/code&gt;, &lt;code&gt;num_speculative_tokens: 5&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total throughput: &lt;strong&gt;2216.39 Tokens/s&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Output throughput: &lt;strong&gt;99.22 Tokens/s&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;TPOT: &lt;strong&gt;63.92 ms&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DSpark (&lt;code&gt;method: dspark&lt;/code&gt;, &lt;code&gt;num_speculative_tokens: 7&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total throughput: &lt;strong&gt;1336.12 Tokens/s&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Output throughput: &lt;strong&gt;59.82 Tokens/s&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;TPOT: &lt;strong&gt;103.08 ms&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Under high-concurrency workloads, DSpark's output throughput (&lt;strong&gt;59.8 TPS&lt;/strong&gt;) did &lt;strong&gt;not improve and instead regressed&lt;/strong&gt;, performing significantly below the original MTP approach (&lt;strong&gt;99.2 TPS&lt;/strong&gt;). TPOT was also higher.  &lt;/p&gt;

&lt;p&gt;The main reason is that the external draft model provided by Red Hat AI achieved a relatively low acceptance rate on the Random dataset. When speculative decoding has insufficient acceptance, the additional draft computation overhead can negatively impact overall throughput.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Performance Summary
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Original GLM-5.2-FP8&lt;/th&gt;
&lt;th&gt;GLM-5.2-FP8-DSpark&lt;/th&gt;
&lt;th&gt;Comparison&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single-concurrency (Playground)&lt;/td&gt;
&lt;td&gt;Output TPS&lt;/td&gt;
&lt;td&gt;≈ 71.8&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;≈ 171.6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;≈ 2.2×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-concurrency 64K/3K&lt;/td&gt;
&lt;td&gt;Total Throughput (TPS)&lt;/td&gt;
&lt;td&gt;2216.39 (MTP)&lt;/td&gt;
&lt;td&gt;1336.12&lt;/td&gt;
&lt;td&gt;≈ 0.60×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-concurrency 64K/3K&lt;/td&gt;
&lt;td&gt;Output Throughput (TPS)&lt;/td&gt;
&lt;td&gt;99.22 (MTP)&lt;/td&gt;
&lt;td&gt;59.82&lt;/td&gt;
&lt;td&gt;≈ 0.60×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-concurrency 64K/3K&lt;/td&gt;
&lt;td&gt;TPOT (ms)&lt;/td&gt;
&lt;td&gt;63.92 (MTP)&lt;/td&gt;
&lt;td&gt;103.08&lt;/td&gt;
&lt;td&gt;Higher&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The performance characteristics of GLM-5.2-FP8-DSpark show a clear trade-off:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single-concurrency / low-concurrency scenarios:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Speculative decoding provides significant benefits. In this test, DSpark achieved &lt;strong&gt;1.2–2.2×&lt;/strong&gt; the throughput of the original GLM-5.2-FP8, making it suitable for interactive workloads that are sensitive to single-request throughput and response latency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High-concurrency scenarios:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
With the external draft model used in this test, the acceptance rate on the Random dataset was relatively low. As a result, throughput did not improve significantly and was even lower than the original MTP approach. It is currently not recommended for similar high-concurrency production workloads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Recommendation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Based on the model and workload tested in this article, DSpark is currently more suitable for &lt;strong&gt;research validation and low-concurrency scenarios&lt;/strong&gt;. For high-concurrency production deployment, it is recommended to wait for draft model versions with higher acceptance rates on these workloads.&lt;br&gt;&lt;br&gt;
&lt;em&gt;(The conclusions above only apply to the draft model and dataset used in this test, and do not represent the upper limit of the DSpark speculative decoding approach.)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks to GPUStack's pluggable vLLM backend architecture, adding a new image version, integrating an external draft model, or switching between different inference configurations can all be completed through the Web UI with just a few clicks. This enables teams to evaluate new models from Day 0 with minimal adaptation effort.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Test Environment: 8× H20-141G ｜ GPUStack v2 ｜ vLLM v0.25.0 (&lt;code&gt;25-custom&lt;/code&gt; image)&lt;/p&gt;

&lt;p&gt;Thanks to the GPUStack community member for sharing this real-world deployment experience.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
      <category>github</category>
    </item>
    <item>
      <title>Where Did Your GPU Resources Go? GPUStack Usage Tracking Gives You the Answer at a Glance</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Wed, 08 Jul 2026 02:17:30 +0000</pubDate>
      <link>https://dev.to/gpustack/where-did-your-gpu-resources-go-gpustack-usage-tracking-gives-you-the-answer-at-a-glance-203b</link>
      <guid>https://dev.to/gpustack/where-did-your-gpu-resources-go-gpustack-usage-tracking-gives-you-the-answer-at-a-glance-203b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;You bought a stack of GPUs and deployed a bunch of models. Then, at the end of the month, your boss asks: “Are these GPUs actually worth the cost?” Can you answer?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If not, this article is for you.&lt;/p&gt;

&lt;p&gt;GPUStack’s new &lt;strong&gt;Usage&lt;/strong&gt; feature is now available. It provides clear visibility into three key types of resource consumption: token usage, GPU/CPU instance runtime, and storage usage.&lt;/p&gt;

&lt;p&gt;Who is using the resources, how much they are using, and which models the usage is associated with — you no longer have to guess.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Why Do You Need It?
&lt;/h2&gt;

&lt;p&gt;In a shared GPU cluster with multiple users and multiple models, the biggest pain point is not always &lt;strong&gt;“not enough compute.”&lt;/strong&gt; More often, it is: &lt;strong&gt;“Where did the compute go?”&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want to calculate costs, but cannot get usage details broken down by user.&lt;/li&gt;
&lt;li&gt;Platform admins want to know which model consumes the most resources, but have to dig through logs.&lt;/li&gt;
&lt;li&gt;Business teams ask for more GPU capacity, but no one can clearly explain the actual utilization of existing resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GPUStack Usage is built to answer exactly these questions. It connects the full workflow from &lt;strong&gt;collection → aggregation → visualization&lt;/strong&gt;, making every unit of compute consumption traceable.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Five Tabs Covering All Usage Scenarios
&lt;/h2&gt;

&lt;p&gt;Click the &lt;strong&gt;bar chart icon&lt;/strong&gt; in the left navigation bar to enter the Usage page. You will see five tabs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tab&lt;/th&gt;
&lt;th&gt;What You Can See&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Summary&lt;/td&gt;
&lt;td&gt;A complete overview of token, compute, and storage usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tokens&lt;/td&gt;
&lt;td&gt;LLM token usage, broken down by model / user / API key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU Instances&lt;/td&gt;
&lt;td&gt;GPU/CPU instance runtime, broken down by instance type / instance / user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Storage usage, broken down by storage volume / user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource Events&lt;/td&gt;
&lt;td&gt;Resource lifecycle audit logs that explain where each number comes from&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What exactly is being measured?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;When It Is Measured&lt;/th&gt;
&lt;th&gt;Granularity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Token&lt;/td&gt;
&lt;td&gt;When an inference request is served through the gateway&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU/CPU Instance&lt;/td&gt;
&lt;td&gt;When an instance is in the “running (billable)” state; usage stops accumulating after the instance is stopped or deleted&lt;/td&gt;
&lt;td&gt;Hourly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Measured from creation to deletion, regardless of whether it is mounted or used&lt;/td&gt;
&lt;td&gt;Hourly&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  3. Scenario 1: View Usage by User, Clearly See Who Used What
&lt;/h2&gt;

&lt;p&gt;This is one of the most important capabilities in a shared cluster. GPUStack has two built-in roles: &lt;strong&gt;Admin&lt;/strong&gt; and &lt;strong&gt;User&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Admin&lt;/strong&gt;: Can view usage across &lt;strong&gt;all users&lt;/strong&gt; and drill down into any member through the &lt;strong&gt;“filter by user”&lt;/strong&gt; control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User&lt;/strong&gt;: Can only view &lt;strong&gt;their own&lt;/strong&gt; usage details and cannot see other users’ data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, platform admins can easily answer questions such as: “How many tokens did this user consume this month?” or “Who used the most GPU hours?” For cost allocation and quota planning, the data is already there.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 The detailed tables in each tab support &lt;strong&gt;grouping by user&lt;/strong&gt;. This is only visible to admins, making each user’s usage bill clear and easy to review.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fauqsprie3vdyt1yui9pl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fauqsprie3vdyt1yui9pl.png" alt="case1--top-user" width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;regular users&lt;/strong&gt;, the Usage page shows a dedicated usage bill of their own: how many tokens they used this month, how many GPU hours they ran, and how much storage they occupied. Everything is clear at a glance. This helps users stay aware of their usage, compare it against their quota, and avoid overuse.&lt;/p&gt;

&lt;p&gt;They cannot see anyone else’s data, so the permission boundary remains clear and the experience is more secure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frw8qhbkyrh73nby6aqgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frw8qhbkyrh73nby6aqgy.png" alt="case1--normal-user" width="800" height="622"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Scenario 2: Break Down Usage by API Key to See Which Application Is Driving Costs
&lt;/h2&gt;

&lt;p&gt;Viewing usage &lt;strong&gt;by user&lt;/strong&gt; gives you a people-oriented perspective. Viewing usage &lt;strong&gt;by API Key&lt;/strong&gt; gives you an application-oriented perspective — and in many cases, applications are the real source of consumption.&lt;/p&gt;

&lt;p&gt;In practice, each connected application or business pipeline usually uses a &lt;strong&gt;dedicated API Key&lt;/strong&gt;. The Tokens tab supports &lt;strong&gt;grouping by API Key&lt;/strong&gt;, so you can directly see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which &lt;strong&gt;application / integration partner&lt;/strong&gt; is continuously consuming tokens&lt;/li&gt;
&lt;li&gt;Whether the cost of a business line has suddenly increased&lt;/li&gt;
&lt;li&gt;Which keys are barely used and can be reclaimed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By combining the dimensions of &lt;strong&gt;users&lt;/strong&gt; and &lt;strong&gt;applications&lt;/strong&gt;, cost attribution becomes much more complete.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fegi1okd2hhynmcpjj5io.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fegi1okd2hhynmcpjj5io.png" alt="case2--top-api-key" width="800" height="625"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Scenario 3: Clearly Track Usage Across Different Types of Models
&lt;/h2&gt;

&lt;p&gt;Running large language models, embedding models, and open-source models of different sizes in the same cluster? No problem.&lt;/p&gt;

&lt;p&gt;At the top of the &lt;strong&gt;Tokens tab&lt;/strong&gt;, GPUStack shows the key metrics directly: &lt;strong&gt;input / output / total tokens&lt;/strong&gt;, &lt;strong&gt;API requests&lt;/strong&gt;, and &lt;strong&gt;number of models used&lt;/strong&gt;. The detailed table below can be grouped by &lt;strong&gt;model&lt;/strong&gt;, showing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input tokens, including &lt;strong&gt;cached input tokens&lt;/strong&gt;, which are marked separately&lt;/li&gt;
&lt;li&gt;Output tokens&lt;/li&gt;
&lt;li&gt;Total tokens&lt;/li&gt;
&lt;li&gt;API requests&lt;/li&gt;
&lt;li&gt;Last active time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets you quickly identify which models are receiving the most traffic, which models were requested but are barely used, and whether a model should be taken offline or scaled up. The data helps you make the decision.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcxekddq35spnft8tllcu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcxekddq35spnft8tllcu.png" alt="case3--top-model" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📌 &lt;strong&gt;Easily verify the effect of cache optimization&lt;/strong&gt;: The &lt;strong&gt;Input Tokens Cached&lt;/strong&gt; field separately marks the portion of input tokens that hit the prompt cache. After optimizing prompt caching, you can check the proportion of this number to directly quantify how many input tokens were saved. Whether the optimization worked is clear at a glance.&lt;/p&gt;

&lt;p&gt;Also: Even if a model has been deleted, its historical usage is still retained in the table and marked as &lt;strong&gt;Deleted&lt;/strong&gt;. It is still included in the total usage, so historical records are not lost.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Scenario 4: GPU Compute Usage Is No Longer a Black Box
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;GPU Instances tab&lt;/strong&gt; breaks down instance runtime clearly. The key is that it distinguishes between two metrics that are often confused:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Instance Hours&lt;/td&gt;
&lt;td&gt;The wall-clock runtime of an instance, regardless of how many GPUs it uses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPU Hours&lt;/td&gt;
&lt;td&gt;Accelerator runtime = runtime × number of GPUs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example, a &lt;strong&gt;2-GPU instance running for 1 hour&lt;/strong&gt; equals &lt;strong&gt;2 GPU hours&lt;/strong&gt;, but only &lt;strong&gt;1 instance hour&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This distinction lets you calculate actual GPU usage instead of being misled by the number of instances. The trend chart can also be grouped by &lt;strong&gt;instance type / instance / user&lt;/strong&gt;, helping you understand the current situation before scaling capacity.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚙️ CPU instances do not have accelerator cards, so they are counted only in &lt;strong&gt;Instance Hours&lt;/strong&gt;, not &lt;strong&gt;GPU Hours&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuvgbog1d0vo9hdxn8x8s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuvgbog1d0vo9hdxn8x8s.png" alt="case4--instance-hours" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Scenario 5: Storage Usage, Including Idle Volumes
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Storage tab&lt;/strong&gt; focuses on storage capacity usage over time. The key metrics are &lt;strong&gt;GB-Days&lt;/strong&gt; and &lt;strong&gt;GB-Hours&lt;/strong&gt;: capacity × duration. Usage can be broken down by &lt;strong&gt;storage volume / user&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The important detail is this: storage is measured &lt;strong&gt;from creation to deletion, regardless of whether it is mounted&lt;/strong&gt;. This means there are no blind spots in the usage records. Even if a volume is not mounted or accessed, as long as it still exists, its usage is counted in GB-Days. It will not disappear from the bill simply because it is “not being used.”&lt;/p&gt;

&lt;p&gt;This makes forgotten idle volumes easy to find. Sort by &lt;strong&gt;GB-Days&lt;/strong&gt;, identify the volumes occupying the most capacity, check whether they are still used by any instance, and clean up what should be removed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwk6ephbwvo5raf4r4e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwk6ephbwvo5raf4r4e2.png" alt="case5--storage" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Scenario 6: Find Zombie Resources and Stop Paying for Waste
&lt;/h2&gt;

&lt;p&gt;After a cluster has been running for a while, it often accumulates resources that no one remembers: models that are no longer called, or instances that were never stopped. They no longer create value, but they still occupy resources.&lt;/p&gt;

&lt;p&gt;For resources that are measured only when used, such as models and GPU/CPU instances, each detailed table includes a &lt;strong&gt;Last Active&lt;/strong&gt; column. It records the last time the resource generated usage. Once the resource is no longer used, usage stops accumulating and Last Active stays at that moment. Long-inactive models and forgotten stopped instances immediately become visible, making cleanup much more targeted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8bv0p92wgmc8tjgq5tui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8bv0p92wgmc8tjgq5tui.png" alt="case6--not-activate" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Scenario 7: View Trends and Plan Capacity Without Guesswork
&lt;/h2&gt;

&lt;p&gt;Both the Summary page and the individual tabs include &lt;strong&gt;trend charts&lt;/strong&gt;. With adjustable &lt;strong&gt;granularity&lt;/strong&gt; by hour / day / week / month, you can see how usage changes over time instead of only looking at a static total.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is usage stable, or is it growing faster?&lt;/li&gt;
&lt;li&gt;When did the growth inflection point occur, and does it match a business launch?&lt;/li&gt;
&lt;li&gt;Based on the current trend, how long can existing capacity last?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the trend is clear, capacity planning moves from guesswork to data-driven decisions. Trend charts can also be &lt;strong&gt;split by group&lt;/strong&gt;, making structural changes easy to spot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8pkyt7enfn8iaztp526.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr8pkyt7enfn8iaztp526.png" alt="case7--trend-1" width="800" height="625"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjqh01diixdainhbupzl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjqh01diixdainhbupzl.png" alt="case7--trend-2" width="800" height="641"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Scenario 8: Every Number Has a Source, and Resource Events Show the Full Lifecycle
&lt;/h2&gt;

&lt;p&gt;Each tab above shows the &lt;strong&gt;result&lt;/strong&gt;: how many GPU hours were used, how many GB-Days were consumed, and so on. The &lt;strong&gt;Resource Events tab&lt;/strong&gt; shows where those numbers come from. The lifecycle of every instance and storage volume is recorded as events.&lt;/p&gt;

&lt;p&gt;Sorted in reverse chronological order, it becomes a resource timeline. The lifecycle of an instance is easy to follow, with colored labels showing each state clearly:&lt;/p&gt;

&lt;p&gt;🟢 &lt;strong&gt;Created&lt;/strong&gt; → 🔵 &lt;strong&gt;Started&lt;/strong&gt; and measured → 🟠 &lt;strong&gt;Stopped&lt;/strong&gt; and no longer measured → 🔴 &lt;strong&gt;Deleted&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trace usage for reconciliation&lt;/strong&gt;: Why does an instance have this number of Instance Hours? Check the period from Started to Stopped, and you can see exactly how long it ran.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter and investigate&lt;/strong&gt;: Filter by &lt;strong&gt;date / resource type / event type / name&lt;/strong&gt; to quickly answer questions such as “which volumes were deleted last week?” or “which instance was repeatedly started and stopped?”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explain inactivity&lt;/strong&gt;: If Last Active in Scenario 6 shows that an instance has stopped generating usage, come here to check when it was Stopped or Deleted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6d15gwlg98w4h16wzvw8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6d15gwlg98w4h16wzvw8.png" alt="case8--resource-event" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Put the Data to Work: Export Usage for Reconciliation
&lt;/h2&gt;

&lt;p&gt;Seeing the data is not enough. You also need to take it out and use it.&lt;/p&gt;

&lt;p&gt;The Tokens, GPU Instances, and Storage tabs all support &lt;strong&gt;export&lt;/strong&gt; through the download icon. You can preview the currently filtered details and then download them. Monthly billing, financial reconciliation, internal reports — once you have the data, you can work with it directly, without asking engineers to write custom scripts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwk5093if7uu0h2j74nu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwk5093if7uu0h2j74nu5.png" alt="case-export" width="799" height="399"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Details That Make Usage Tracking Reliable
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Unified Time Zone&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All timestamps across tabs, including trend buckets, Last Active, and event time, are displayed using the same &lt;strong&gt;rollup time zone&lt;/strong&gt;. This ensures that calendar boundaries are aligned across all tabs. It can be configured through the &lt;code&gt;GPUSTACK_USAGE_ROLLUP_TIMEZONE&lt;/code&gt; environment variable and follows the server’s local time zone by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexible Common Controls&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Date range, defaulting to the last 30 days, filtering by user / model / API Key, refresh, metric switching, grouping, and granularity adjustment are all available out of the box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Retention and Archiving&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aggregated token, compute, and storage usage data is retained for about 13 months by default, and then archived by background tasks. The retention window and archive schedule can be configured through the &lt;code&gt;GPUSTACK_*_RETENTION_MONTHS&lt;/code&gt; and &lt;code&gt;GPUSTACK_*_ARCHIVE_CRON&lt;/code&gt; environment variables.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Compute is expensive, but compute you cannot see clearly is even more expensive.&lt;/p&gt;

&lt;p&gt;GPUStack Usage makes every token, every GPU hour, and every GB of storage &lt;strong&gt;measurable, traceable, and attributable&lt;/strong&gt;. Whether you are in finance handling cost allocation, an administrator planning capacity, or a business owner trying to prove ROI, it gives you answers backed by data.&lt;/p&gt;

&lt;p&gt;Upgrade to the latest version of GPUStack, open the Usage page, and see where your compute resources are really going.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
      <category>gpu</category>
    </item>
    <item>
      <title>Day 0 Benchmark: Deploying DeepSeek-V4-Flash-DSpark on GPUStack Doubles Throughput</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Wed, 01 Jul 2026 14:05:03 +0000</pubDate>
      <link>https://dev.to/gpustack/day-0-benchmark-deploying-deepseek-v4-flash-dspark-on-gpustack-doubles-throughput-1b8h</link>
      <guid>https://dev.to/gpustack/day-0-benchmark-deploying-deepseek-v4-flash-dspark-on-gpustack-doubles-throughput-1b8h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on a community benchmark contributed by a GPUStack user. DeepSeek-V4-Flash-DSpark enhances DeepSeek-V4-Flash by adding a Speculative Decoding module. Using the same model weights with an additional speculative decoder, it significantly improves both inference throughput and Time to First Token (TTFT).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On Day 0 of the model release, a GPUStack community member deployed and benchmarked DeepSeek-V4-Flash-DSpark on an 8× H20-141G setup, comparing it against the original DeepSeek-V4-Flash (DSV4F) under identical deployment settings. Here are the key results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single-stream throughput&lt;/strong&gt;: In the 1K input / 1K output workload, DSpark achieved 195 tokens/s, approximately &lt;strong&gt;2×&lt;/strong&gt; the throughput of the original model (96 tokens/s)；&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overall throughput&lt;/strong&gt;: In the 64K input / 3K output workload with 10 concurrent requests, DSpark reached &lt;strong&gt;338 tokens/s&lt;/strong&gt;, approximately &lt;strong&gt;1.7×&lt;/strong&gt; higher than the original (198 tokens/s)；&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to First Token (TTFT)&lt;/strong&gt;: Reduced to roughly &lt;strong&gt;half that of the original model&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following sections walk through the complete deployment process and benchmark results.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Deploying DSpark on GPUStack
&lt;/h2&gt;

&lt;p&gt;GPUStack comes with the SGLang inference backend built in. To deploy DSpark, simply add a container image that supports the model. The entire process can be completed in just a few clicks through the web UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  ① Go to Inference Backends and edit SGLang.
&lt;/h3&gt;

&lt;p&gt;From the left navigation menu, go to &lt;strong&gt;Inference Backends&lt;/strong&gt;, locate the SGLang card, then click the menu in the upper-right corner and select &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg5szbu325833veqllr7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg5szbu325833veqllr7b.png" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ② Add a DSpark-compatible image
&lt;/h3&gt;

&lt;p&gt;Under Version Configuration, click Add Version to create a new version named dspark, then specify the following container image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;swr.cn-north-4.myhuaweicloud.com/desaysv/gpustack/sglang-dspark:v1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select &lt;strong&gt;CUDA&lt;/strong&gt; as the framework. Set the image entrypoint override to &lt;code&gt;sglang serve&lt;/code&gt;, and set the command to: &lt;code&gt;--model-path {{model_path}} --host {{worker_ip}} --port {{port}}&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmdefbjjeishk71217jr5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmdefbjjeishk71217jr5.png" width="800" height="1407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ③ Create a Deployment
&lt;/h3&gt;

&lt;p&gt;Return to the &lt;strong&gt;Deployments&lt;/strong&gt; page and click &lt;strong&gt;Deploy Model&lt;/strong&gt; in the upper-right corner. For &lt;strong&gt;Source&lt;/strong&gt;, select &lt;strong&gt;ModelScope&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvrekooi9fhhyggrqvmob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvrekooi9fhhyggrqvmob.png" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ④ Select the Model and Inference Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Search for and select &lt;code&gt;deepseek-ai/DeepSeek-V4-Flash-DSpark&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;Inference Backend&lt;/strong&gt; to &lt;strong&gt;SGLang&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;dspark-custom&lt;/strong&gt; as the backend version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flbjj5d96vo8ctp5u5e87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flbjj5d96vo8ctp5u5e87.png" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑤ Configure Backend Parameters
&lt;/h3&gt;

&lt;p&gt;Under &lt;strong&gt;Advanced&lt;/strong&gt;, configure the backend parameters as follows (using an &lt;strong&gt;8× H20-141G&lt;/strong&gt; setup as an example):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--context-length&lt;/span&gt; 1000000
&lt;span class="nt"&gt;--trust-remote-code&lt;/span&gt;
&lt;span class="nt"&gt;--tp-size&lt;/span&gt; 8
&lt;span class="nt"&gt;--ep-size&lt;/span&gt; 8
&lt;span class="nt"&gt;--moe-runner-backend&lt;/span&gt; flashinfer_mxfp4
&lt;span class="nt"&gt;--speculative-moe-runner-backend&lt;/span&gt; flashinfer_mxfp4
&lt;span class="nt"&gt;--speculative-algorithm&lt;/span&gt; DSPARK
&lt;span class="nt"&gt;--speculative-eagle-topk&lt;/span&gt; 1
&lt;span class="nt"&gt;--speculative-num-steps&lt;/span&gt; 1
&lt;span class="nt"&gt;--mem-fraction-static&lt;/span&gt; 0.85
&lt;span class="nt"&gt;--cuda-graph-max-bs&lt;/span&gt; 32
&lt;span class="nt"&gt;--max-running-requests&lt;/span&gt; 32
&lt;span class="nt"&gt;--disable-overlap-schedule&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fke21iuwvmucrr8w775ix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fke21iuwvmucrr8w775ix.png" width="800" height="1609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑥ Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Add the following environment variable to ensure the required dependencies are installed correctly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PYPI_PACKAGES_INSTALL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-U distro -i https://mirrors.aliyun.com/pypi/simple/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbr00zy47ilmw3fp08rh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbr00zy47ilmw3fp08rh2.png" width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑦ Start the Deployment and Monitor the Logs
&lt;/h3&gt;

&lt;p&gt;Once submitted, GPUStack will start the deployment. In the logs, you should see &lt;strong&gt;CUDA Graph capture&lt;/strong&gt;, &lt;code&gt;Application startup complete&lt;/code&gt;, and &lt;strong&gt;Uvicorn&lt;/strong&gt; listening on the inference port, indicating that the model has started successfully:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foc9r01mt1ta41zx8bdgq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foc9r01mt1ta41zx8bdgq.png" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑧ Verify the Deployment Status
&lt;/h3&gt;

&lt;p&gt;Once the instance reaches the &lt;strong&gt;Running&lt;/strong&gt; state, the deployment is complete.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj0tageo9luini1ynv8nn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fj0tageo9luini1ynv8nn.png" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑨ Verify the Deployment
&lt;/h3&gt;

&lt;p&gt;Open the &lt;strong&gt;Playground&lt;/strong&gt; and send a few prompts to the model. The real-time throughput indicator in the lower-right corner should show an output rate of &lt;strong&gt;185.94 tokens/s&lt;/strong&gt;, with single-stream throughput remaining stable at around &lt;strong&gt;200 tokens/s&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑩ View the Inference Service Port
&lt;/h3&gt;

&lt;p&gt;If you want to run benchmarks directly against the service, open the instance details to find the inference service IP address and port (in this example, &lt;code&gt;10.91.3.213:40048&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Benchmark Results: DSpark vs. DSV4F
&lt;/h2&gt;

&lt;p&gt;Under &lt;strong&gt;identical hardware and deployment settings&lt;/strong&gt;, we benchmarked the original &lt;strong&gt;DeepSeek-V4-Flash (with MTP enabled)&lt;/strong&gt; against &lt;strong&gt;DSpark&lt;/strong&gt; across two workloads. All benchmarks were conducted using SGLang's built-in &lt;code&gt;bench_serving&lt;/code&gt; tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 1: 1K Input / 1K Output (Single Request)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;HF_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://hf-mirror.com python3 &lt;span class="nt"&gt;-m&lt;/span&gt; sglang.bench_serving &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--backend&lt;/span&gt; sglang &lt;span class="nt"&gt;--port&lt;/span&gt; 40048 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dataset-name&lt;/span&gt; random &lt;span class="nt"&gt;--random-input-len&lt;/span&gt; 1024 &lt;span class="nt"&gt;--random-output-len&lt;/span&gt; 1024 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--random-range-ratio&lt;/span&gt; 1.0 &lt;span class="nt"&gt;--num-prompts&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--max-concurrency&lt;/span&gt; 1 &lt;span class="nt"&gt;--request-rate&lt;/span&gt; inf &lt;span class="nt"&gt;--host&lt;/span&gt; &amp;lt;Inference Server IP Address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Original DSV4F:&lt;/strong&gt; Output throughput: &lt;strong&gt;96.20 tokens/s&lt;/strong&gt;, TTFT: &lt;strong&gt;300.45 ms&lt;/strong&gt;, Accept length: &lt;strong&gt;2.71&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsosxnn2he6leuj33011g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsosxnn2he6leuj33011g.jpg" width="729" height="786"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DSpark（DSV4FD）：&lt;/strong&gt; Output throughput &lt;strong&gt;195.18 tok/s&lt;/strong&gt;，TTFT 129.34 ms，Accept length 4.42&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9hvtzociwrt87bmyxdf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9hvtzociwrt87bmyxdf.jpg" width="800" height="877"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Single-stream throughput reached 195 tokens/s&lt;/strong&gt;, approximately &lt;strong&gt;2×&lt;/strong&gt; that of the original DSV4F (&lt;strong&gt;96 tokens/s&lt;/strong&gt;), while &lt;strong&gt;Time to First Token (TTFT)&lt;/strong&gt; was reduced to &lt;strong&gt;about half&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Scenario 2: 64K Input / 3K Output (10 Concurrent Requests)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;HF_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://hf-mirror.com python3 &lt;span class="nt"&gt;-m&lt;/span&gt; sglang.bench_serving &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--backend&lt;/span&gt; sglang &lt;span class="nt"&gt;--port&lt;/span&gt; 40048 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dataset-name&lt;/span&gt; random &lt;span class="nt"&gt;--random-input-len&lt;/span&gt; 64000 &lt;span class="nt"&gt;--random-output-len&lt;/span&gt; 3000 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--random-range-ratio&lt;/span&gt; 1.0 &lt;span class="nt"&gt;--num-prompts&lt;/span&gt; 10 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--max-concurrency&lt;/span&gt; 1 &lt;span class="nt"&gt;--request-rate&lt;/span&gt; inf &lt;span class="nt"&gt;--host&lt;/span&gt; &amp;lt;Inference Server IP Address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Original DSV4F (MTP enabled):&lt;/strong&gt; Output throughput: &lt;strong&gt;198.60 tokens/s&lt;/strong&gt;, Speculative acceptance rate: &lt;strong&gt;20.91%&lt;/strong&gt;, Acceptance length: &lt;strong&gt;1.21&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ecrlzegx3dym00ssnqt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ecrlzegx3dym00ssnqt.png" width="799" height="579"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DSpark（DSV4FD）：&lt;/strong&gt; Output throughput &lt;strong&gt;338.17 tok/s&lt;/strong&gt;，Accept length 4.90&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqrdb5b2teqqhqbiy3987.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqrdb5b2teqqhqbiy3987.jpg" width="780" height="888"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the long-context workload, &lt;strong&gt;DSpark&lt;/strong&gt; achieved &lt;strong&gt;338 tokens/s&lt;/strong&gt;, approximately &lt;strong&gt;1.7×&lt;/strong&gt; the throughput of the original DSV4F (&lt;strong&gt;198 tokens/s&lt;/strong&gt;), nearly doubling overall throughput.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Original DSV4F&lt;/th&gt;
&lt;th&gt;DSpark (DSV4FD)&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1K Input / 1K Output&lt;/td&gt;
&lt;td&gt;Output Throughput (tokens/s)&lt;/td&gt;
&lt;td&gt;96.20&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;195.18&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;≈ 2.0×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1K Input / 1K Output&lt;/td&gt;
&lt;td&gt;TTFT (ms)&lt;/td&gt;
&lt;td&gt;300.45&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;129.34&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;≈ 0.43×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1K Input / 1K Output&lt;/td&gt;
&lt;td&gt;Acceptance Length&lt;/td&gt;
&lt;td&gt;2.71&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.42&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;64K Input / 3K Output&lt;/td&gt;
&lt;td&gt;Output Throughput (tokens/s)&lt;/td&gt;
&lt;td&gt;198.60&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;338.17&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;≈ 1.7×&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;64K Input / 3K Output&lt;/td&gt;
&lt;td&gt;Acceptance Length&lt;/td&gt;
&lt;td&gt;1.21&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.90&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Across both single-request and long-context workloads, &lt;strong&gt;DeepSeek-V4-Flash-DSpark&lt;/strong&gt; consistently delivered &lt;strong&gt;around 2× the throughput&lt;/strong&gt; of the original &lt;strong&gt;DSV4F&lt;/strong&gt;, while reducing &lt;strong&gt;Time to First Token (TTFT)&lt;/strong&gt; to &lt;strong&gt;roughly half&lt;/strong&gt;. Achieving these gains requires nothing more than switching to the DSpark model weights and container image with the integrated speculative decoding module.&lt;/p&gt;

&lt;p&gt;With GPUStack's built-in &lt;strong&gt;SGLang&lt;/strong&gt; inference backend, the entire deployment can be completed in just a few clicks through the web UI, making the model &lt;strong&gt;production-ready on Day 0&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Benchmark environment:&lt;/strong&gt; 8× H20-141G | GPUStack v2 | SGLang 0.5.14 (using the &lt;code&gt;dspark-custom&lt;/code&gt; image based on a patched SGLang 0.5.14)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acknowledgments:&lt;/strong&gt; Thanks to the GPUStack community member for sharing the benchmark results.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
      <category>deepseek</category>
    </item>
    <item>
      <title>GPUStack v2.2: From Model Serving to Token Operations, from Compute Pooling to GPU-as-a-Service</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Tue, 30 Jun 2026 02:34:35 +0000</pubDate>
      <link>https://dev.to/gpustack/gpustack-v22-from-model-serving-to-token-operations-from-compute-pooling-to-gpu-as-a-service-28im</link>
      <guid>https://dev.to/gpustack/gpustack-v22-from-model-serving-to-token-operations-from-compute-pooling-to-gpu-as-a-service-28im</guid>
      <description>&lt;p&gt;Deploying a model and bringing it online is only the starting point of AI service delivery.&lt;/p&gt;

&lt;p&gt;As large language model applications move into scaled production, AI infrastructure is entering an inevitable phase of maturity — from simply &lt;strong&gt;being able to run&lt;/strong&gt; to becoming &lt;strong&gt;operations-ready&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This shift is not just about adding more features. It reflects an evolution in platform positioning: from reliably serving inference workloads to becoming the &lt;strong&gt;infrastructure foundation&lt;/strong&gt; that can truly support enterprise AI service delivery.&lt;/p&gt;

&lt;p&gt;At this stage, the core challenge lies in advancing two areas in parallel: model serving must deliver operations-grade &lt;strong&gt;reliability&lt;/strong&gt; and &lt;strong&gt;visibility&lt;/strong&gt;, while compute management must expand from “serving inference workloads” to “unified allocation of the diverse resources required by AI.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GPUStack v2.2&lt;/strong&gt; continues to move deeper in both directions: model serving is evolving from &lt;strong&gt;available&lt;/strong&gt; to &lt;strong&gt;operations-ready&lt;/strong&gt;, while compute management is extending from &lt;strong&gt;unified scheduling&lt;/strong&gt; to &lt;strong&gt;on-demand services&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deepening Support for Model Inference Scenarios and Lifecycle Management
&lt;/h2&gt;

&lt;p&gt;The stability of model serving is not only a deployment-stage concern. After an instance starts running, issues such as &lt;strong&gt;OOM errors&lt;/strong&gt;, &lt;strong&gt;hanging inference requests&lt;/strong&gt;, and &lt;strong&gt;silent process crashes&lt;/strong&gt; are often the more common problems in production environments.&lt;/p&gt;

&lt;p&gt;Previously, GPUStack’s health checks mainly covered the &lt;strong&gt;startup phase&lt;/strong&gt;. Once an instance started successfully, the platform had no way to detect issues that occurred later. Faulty instances could remain in the service pool and continue receiving traffic, resulting in &lt;strong&gt;silent failures&lt;/strong&gt; that would only be addressed after someone noticed and handled them manually.&lt;/p&gt;

&lt;p&gt;In v2.2, health probing is extended across the &lt;strong&gt;entire runtime lifecycle&lt;/strong&gt;. The platform continuously checks the actual inference capability of each instance. When an abnormal instance is detected, it is immediately removed from the service pool and automatically restarted. Once recovered, it is automatically added back. Service availability is now proactively maintained by the platform, rather than relying on manual inspections or user reports.&lt;/p&gt;

&lt;p&gt;Troubleshooting capabilities have also been systematically enhanced. In production environments, what teams often need most is a complete record of what happened at the time of failure. Previously, this meant logging into the terminal and manually checking logs. v2.2 introduces three types of log access:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Historical logs before restart&lt;/strong&gt;, allowing you to view the complete output before an instance crashed, instead of losing access to past failure logs after a restart;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Distributed sub-instance logs&lt;/strong&gt;, allowing you to inspect the output of each node separately in multi-node deployments and quickly identify where the issue occurred;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ray container logs&lt;/strong&gt;, allowing you to view Ray container logs directly in the UI without troubleshooting through terminal commands.&lt;/p&gt;

&lt;p&gt;Most production troubleshooting workflows can now be completed end to end within the GPUStack UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk6pzercnahrngnkiwsgq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk6pzercnahrngnkiwsgq.png" alt="image-20260617105156970" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For distributed inference, v2.2 introduces &lt;strong&gt;vLLM MP auto-distributed mode&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Previously, GPUStack only supported Ray-based auto-distributed vLLM deployments. MP-based distributed deployments had to be configured manually, and GPUStack could not automatically spin up all distributed instances.&lt;/p&gt;

&lt;p&gt;With the rapid evolution of vLLM, the new MP-based distributed mode offers clear advantages over Ray-based auto-distributed deployments in terms of operational overhead and inference performance.&lt;/p&gt;

&lt;p&gt;Users can now choose the vLLM auto-distributed deployment strategy that best fits their needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F724hp0ht9qe7ppvgxn80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F724hp0ht9qe7ppvgxn80.png" alt="image-20260617103853807" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another notable update is support for &lt;strong&gt;Multi-LoRA&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In enterprise environments, fine-tuning models for different business scenarios is a common requirement. Previously, each &lt;strong&gt;LoRA Adapter&lt;/strong&gt; had to run as a separate model instance, causing &lt;strong&gt;GPU memory overhead&lt;/strong&gt; to grow linearly with the number of tasks and leading to significant resource waste.&lt;/p&gt;

&lt;p&gt;With v2.2, multiple LoRA Adapters can be mounted to the &lt;strong&gt;same base model instance&lt;/strong&gt; and switched dynamically. This allows the same hardware to support more fine-tuned tasks while significantly improving &lt;strong&gt;GPU memory utilization&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Token Usage Governance for Model Services
&lt;/h2&gt;

&lt;p&gt;Models may be running, but where exactly are tokens being consumed? This question may not be obvious at an early stage with limited usage. But once multiple teams and applications start sharing the same platform, it quickly becomes an operational pain point.&lt;/p&gt;

&lt;p&gt;GPUStack previously supported usage statistics by &lt;strong&gt;model&lt;/strong&gt; and by &lt;strong&gt;user&lt;/strong&gt;, helping teams understand overall consumption trends.&lt;/p&gt;

&lt;p&gt;However, these two dimensions were not sufficient for precise attribution.&lt;/p&gt;

&lt;p&gt;When different applications and business lines share multiple keys under the same user account, &lt;strong&gt;usage cannot be clearly separated&lt;/strong&gt;, making cost accounting difficult to perform.&lt;/p&gt;

&lt;p&gt;v2.2 introduces usage statistics at the &lt;strong&gt;API Key level&lt;/strong&gt;. Token consumption for each key is &lt;strong&gt;metered independently&lt;/strong&gt;, allowing administrators to clearly see which caller is consuming what, and how much. This provides a direct basis for cross-team &lt;strong&gt;cost attribution&lt;/strong&gt; and &lt;strong&gt;quota management&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fph95qhcffarm0igpxain.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fph95qhcffarm0igpxain.png" alt="image-20260617115813850" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwy5ixwnqg2y2lptxmob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwy5ixwnqg2y2lptxmob.png" alt="image-20260617115902612" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foktnc66pp64jdu7ac6ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Foktnc66pp64jdu7ac6ec.png" alt="image-20260617122430446" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjr0pzufk0uvh48ejncx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjr0pzufk0uvh48ejncx.png" alt="image-20260617122452580" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another important change is giving visibility back to users. Previously, users who wanted to understand their own consumption had to ask administrators to pull the data for them.&lt;/p&gt;

&lt;p&gt;v2.2 introduces self-service personal usage queries on the user side. Consumption history by model and by time range can now be viewed directly in the UI, without going through a request process.&lt;/p&gt;

&lt;p&gt;Once metering capabilities are in place, token consumption is no longer a &lt;strong&gt;black box&lt;/strong&gt;. It becomes operational data that can support &lt;strong&gt;quota allocation&lt;/strong&gt;, &lt;strong&gt;internal chargeback&lt;/strong&gt;, and &lt;strong&gt;cost analysis&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhanced Production Deployment Capabilities
&lt;/h2&gt;

&lt;p&gt;Platform capabilities can only be fully realized when supported by a solid deployment experience. In v2.2, GPUStack addresses key gaps in enterprise production deployment across three areas.&lt;/p&gt;

&lt;p&gt;Kubernetes has become a mainstream choice for enterprise infrastructure. However, deploying GPUStack in K8s environments previously lacked a standardized cloud-native path.&lt;/p&gt;

&lt;p&gt;v2.2 provides an official &lt;strong&gt;Helm Chart&lt;/strong&gt;, enabling installation and configuration through Helm in a single streamlined process. This allows GPUStack to fit directly into existing &lt;strong&gt;GitOps workflows&lt;/strong&gt; and &lt;strong&gt;CI/CD&lt;/strong&gt; systems, significantly reducing the operational cost of deployment and upgrades.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg5ik101obp470lrunazf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fg5ik101obp470lrunazf.png" alt="image-20260617111056555" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;v2.2 also expands database compatibility with support for OceanBase and openGauss, giving teams more flexibility in enterprise deployment environments.&lt;/p&gt;

&lt;p&gt;On the network topology side, v2.2 supports a Worker-to-Server one-way access mode.&lt;/p&gt;

&lt;p&gt;In cross-region or cross-network-boundary deployment scenarios, many environments make it difficult to establish bidirectional connectivity between Server and Worker.&lt;/p&gt;

&lt;p&gt;With one-way networking, Worker nodes only need to access the Server, while the Server does not need to initiate reverse connections. This removes a key networking barrier for unified management of multi-region clusters.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Compute Pooling to GPU Services
&lt;/h2&gt;

&lt;p&gt;Unified scheduling of heterogeneous compute resources has always been one of GPUStack’s core capabilities — bringing GPUs from different vendors and with different specifications into a single compute pool for unified scheduling and monitoring. Previously, however, this compute pool primarily served one scenario: &lt;strong&gt;inference&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Data scientists often need an &lt;strong&gt;interactive development environment&lt;/strong&gt;, while algorithm engineers may need &lt;strong&gt;dedicated GPUs&lt;/strong&gt; for experimentation and debugging. In many teams, these needs were handled outside GPUStack through separate systems, resulting in fragmented &lt;strong&gt;resource allocation and metering&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;v2.2 introduces the &lt;strong&gt;GPU Instance Service&lt;/strong&gt;, bringing the process of “allocating an isolated GPU environment” under unified platform management.&lt;/p&gt;

&lt;p&gt;Users can request isolated GPU instances on demand, specify the GPU vendor, model, and quantity, and select runtime templates that include storage mounts and port configurations. Once the instance is ready, they can access it through SSH or the web.&lt;/p&gt;

&lt;p&gt;Usage is metered centrally by the platform and shares the same scheduling and usage system as inference services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1jmrc2xg81dzopvozkwv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1jmrc2xg81dzopvozkwv.png" alt="image-20260617102206612" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxx2wlfhhg03i5zrjppei.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxx2wlfhhg03i5zrjppei.png" alt="image-20260617110217961" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This marks an expansion of GPUStack’s compute service model: the same compute resource pool can serve as the foundation for inference services, while also being exposed as on-demand GPU instances.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;unified scheduling and unified metering&lt;/strong&gt;, management no longer becomes fragmented simply because resources are used in different scenarios. Future capabilities such as &lt;strong&gt;resource scheduling for training and fine-tuning&lt;/strong&gt; and more fine-grained &lt;strong&gt;virtualized compute partitioning&lt;/strong&gt; can naturally build on this foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Next Stage of AI Infrastructure Platforms
&lt;/h2&gt;

&lt;p&gt;The evolution of AI infrastructure follows a clear path: from &lt;strong&gt;being able to run models&lt;/strong&gt;, to &lt;strong&gt;operating model services reliably&lt;/strong&gt;, and then to &lt;strong&gt;unified management and allocation of the compute resources required by AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;v2.2 takes a step forward in both dimensions. On the model serving side, deeper inference scenario support, improved instance lifecycle management, a token usage governance system, and enhanced production deployment capabilities provide the foundation for scaled service delivery.&lt;/p&gt;

&lt;p&gt;On the compute side, the introduction of the GPU Instance Service expands resource allocation and metering beyond inference scenarios.&lt;/p&gt;

&lt;p&gt;Both directions point toward the same goal: making GPUStack an infrastructure foundation that enterprises can truly rely on for AI service delivery.&lt;/p&gt;

&lt;p&gt;Get started:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub: &lt;a href="https://github.com/gpustack/gpustack" rel="noopener noreferrer"&gt;https://github.com/gpustack/gpustack&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation: &lt;a href="https://docs.gpustack.ai" rel="noopener noreferrer"&gt;https://docs.gpustack.ai&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  GPUStack v2.2 Enterprise Edition: Coming Soon
&lt;/h2&gt;

&lt;p&gt;The v2.2 open-source release lays the foundation for platform-level operational capabilities.&lt;/p&gt;

&lt;p&gt;In more complex enterprise environments, there is another layer of capabilities that the open-source edition is not designed to fully cover. When a platform needs to serve multiple isolated tenants, manage compute consumption down to each API Key and model route, ensure end-to-end high availability, and support Token/GPU billing management, these are the challenges that &lt;strong&gt;GPUStack Enterprise Edition&lt;/strong&gt; is built to address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GPUStack v2.2 Enterprise Edition&lt;/strong&gt; is designed for enterprise scenarios that require organization-level governance and commercial operations. It will support &lt;strong&gt;multi-tenant isolation&lt;/strong&gt;, &lt;strong&gt;fine-grained quota, rate limiting, and access control&lt;/strong&gt;, &lt;strong&gt;production-grade high availability&lt;/strong&gt;, &lt;strong&gt;resource topology visualization&lt;/strong&gt;, and &lt;strong&gt;billing management&lt;/strong&gt;. Stay tuned.&lt;/p&gt;

&lt;p&gt;If you are interested in the Enterprise Edition, feel free to contact us to learn more and explore early access opportunities.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Contact us: &lt;a href="https://gpustack.ai/contact/" rel="noopener noreferrer"&gt;https://gpustack.ai/contact/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
    </item>
    <item>
      <title>GPUStack MaxKB: Build a Powerful and Easy-to-Use Open-Source Enterprise AI Agent Platform</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Tue, 10 Mar 2026 02:54:50 +0000</pubDate>
      <link>https://dev.to/gpustack/gpustack-x-maxkb-build-a-powerful-and-easy-to-use-open-source-enterprise-ai-agent-platform-1mb8</link>
      <guid>https://dev.to/gpustack/gpustack-x-maxkb-build-a-powerful-and-easy-to-use-open-source-enterprise-ai-agent-platform-1mb8</guid>
      <description>&lt;h1&gt;
  
  
  GPUStack × MaxKB: Build a Powerful and Easy-to-Use Open-Source Enterprise AI Agent Platform
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;: By leveraging GPUStack for efficient model deployment and management, and connecting those models to MaxKB, you can easily build an AI assistant with &lt;strong&gt;knowledge base retrieval + intelligent Q&amp;amp;A&lt;/strong&gt; capabilities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As AI applications become increasingly common within organizations, more teams are beginning to focus on two core challenges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;How to efficiently manage and deploy local large models&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to quickly build enterprise knowledge bases and AI Agents&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are looking for solutions to both problems, the combination of &lt;strong&gt;GPUStack + MaxKB&lt;/strong&gt; is well worth exploring.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPUStack&lt;/strong&gt;: Focuses on GPU resource management and model deployment, supporting multi-node clusters and multi-model services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MaxKB&lt;/strong&gt;: An open-source enterprise knowledge base and AI application platform that enables rapid development of knowledge-based Q&amp;amp;A systems and AI Agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By connecting &lt;strong&gt;GPUStack-provided model services to MaxKB&lt;/strong&gt;, you can easily build a &lt;strong&gt;practical enterprise AI knowledge assistant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article will walk through the entire process from scratch.&lt;/p&gt;

&lt;h1&gt;
  
  
  📌 What You'll Learn
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Deploy the latest &lt;strong&gt;GPUStack v2.1.0&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Deploy required models in GPUStack&lt;/li&gt;
&lt;li&gt;Obtain GPUStack model connection information&lt;/li&gt;
&lt;li&gt;Deploy &lt;strong&gt;MaxKB&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Connect GPUStack models in MaxKB&lt;/li&gt;
&lt;li&gt;Practical example: Build a &lt;strong&gt;GPUStack documentation knowledge base&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Install GPUStack v2.1.0
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Install GPUStack Server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; gpustack-server &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt; unless-stopped &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 80:80 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; gpustack-data:/var/lib/gpustack &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; /data/gpustack_cache:/var/lib/gpustack/cache &lt;span class="se"&gt;\&lt;/span&gt;
  gpustack/gpustack:v2.1.0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bootstrap-password&lt;/span&gt; &lt;span class="s2"&gt;"123"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--debug&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9h0e1tc39w4ywj2lxpz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9h0e1tc39w4ywj2lxpz.png" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After running the command above, open your browser and visit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;http://your_host_ip
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will enter the &lt;strong&gt;GPUStack UI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Default login credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;admin / 123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkr2u7axddu3iztbcu9t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpkr2u7axddu3iztbcu9t.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create a Cluster
&lt;/h2&gt;

&lt;p&gt;GPUStack manages worker nodes in units called &lt;strong&gt;Clusters&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When deploying GPUStack Server for the first time, you will be prompted to create your first cluster. Click:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Your First Cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow the UI instructions to complete the setup.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can also go to the &lt;strong&gt;Clusters&lt;/strong&gt; page from the sidebar and click &lt;strong&gt;Add Cluster&lt;/strong&gt; to create one manually.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2gtyibvn40543z3jxov3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2gtyibvn40543z3jxov3.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vkvxvmorhy10g8asyoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3vkvxvmorhy10g8asyoa.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3axbbhehoqre4jx66ob3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3axbbhehoqre4jx66ob3.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Add a Worker
&lt;/h2&gt;

&lt;p&gt;After creating a cluster, the system will prompt you to &lt;strong&gt;Add Worker&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Follow the instructions in the UI.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can also add one manually via the &lt;strong&gt;Workers&lt;/strong&gt; page in the sidebar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawy5nphxjgt67h3goj0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawy5nphxjgt67h3goj0a.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabpe92adno4a57t0ez0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabpe92adno4a57t0ez0z.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5v8saioaklguhlaxwnxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5v8saioaklguhlaxwnxp.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the diagnostic command provided in the guide interface.&lt;/p&gt;

&lt;p&gt;If the drivers and container runtime are correctly installed, you will see two &lt;strong&gt;OK&lt;/strong&gt; messages.&lt;/p&gt;

&lt;p&gt;If &lt;strong&gt;not configured&lt;/strong&gt; appears, follow the provided links to check dependency documentation and install the missing components according to your environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filo1thxijfqzoolpx3ai.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Filo1thxijfqzoolpx3ai.png" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6k60htirgwlwxb77cj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq6k60htirgwlwxb77cj7.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Model Cache Volume Mount&lt;/strong&gt;: Mount this directory to the model cache directory &lt;code&gt;/var/lib/gpustack/cache&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPUStack Data Volume&lt;/strong&gt;: Mount this directory to the data directory &lt;code&gt;/var/lib/gpustack&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07bslxly0i1ap7s8byfc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07bslxly0i1ap7s8byfc.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then run the Worker startup command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; gpustack-worker &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=gpustack-worker"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"GPUSTACK_TOKEN=gpustack_7b42996d3f5571d5_8181f986537c100369eaa2dfcf6d6359"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;unless-stopped &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--privileged&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;host &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--volume&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--volume&lt;/span&gt; gpustack-worker-data:/var/lib/gpustack &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--volume&lt;/span&gt; /data/gpustack_cache:/var/lib/gpustack/cache &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--runtime&lt;/span&gt; nvidia &lt;span class="se"&gt;\&lt;/span&gt;
   gpustack/gpustack:v2.1.0 &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--server-url&lt;/span&gt; http://192.168.50.14 &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;--worker-ip&lt;/span&gt; 192.168.50.14
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Deploy Models in GPUStack
&lt;/h1&gt;

&lt;p&gt;Click &lt;strong&gt;Deployments&lt;/strong&gt; in the sidebar to open the model deployment page.&lt;/p&gt;

&lt;p&gt;If no models are currently deployed, you will see a &lt;strong&gt;Deploy Now&lt;/strong&gt; button in the center of the page.&lt;/p&gt;

&lt;p&gt;Click it to enter the &lt;strong&gt;Model Catalog&lt;/strong&gt;, select the desired model, and follow the prompts to deploy it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx10dblgvn4h3pij5z3ij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx10dblgvn4h3pij5z3ij.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Additional deployment methods are available under the &lt;strong&gt;Deploy Model&lt;/strong&gt; menu in the top-right corner.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For this tutorial, we deploy the following three models:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Qwen3-Reranker-4B&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Qwen3-Embedding-4B&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Qwen3.5-35B-A3B&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;GPU memory allocation can be adjusted according to your environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Deploy Qwen3-Reranker-4B
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjibvn5koxi1ct74qsd5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjibvn5koxi1ct74qsd5z.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3n12cp4z72r2cl1ov9p2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3n12cp4z72r2cl1ov9p2.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After deployment, you can test it in the &lt;strong&gt;Playground&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx51lidduddb6adlj1fin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx51lidduddb6adlj1fin.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy Qwen3-Embedding-4B
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5k5av21dql29mtfcaemx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5k5av21dql29mtfcaemx.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsau5d2d7fxy6ro5g97gt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsau5d2d7fxy6ro5g97gt.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After deployment, test it in the Playground.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgac5xvjqrp9730t2q3sr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgac5xvjqrp9730t2q3sr.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploy Qwen3.5-35B-A3B
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Here we additionally set the &lt;strong&gt;PYPI_PACKAGES_INSTALL&lt;/strong&gt; environment variable to upgrade the &lt;code&gt;transformers&lt;/code&gt; library.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyobzc1l0h70325hxz3ab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyobzc1l0h70325hxz3ab.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xaluy944pfnelo9ze5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xaluy944pfnelo9ze5e.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After deployment, test it in the &lt;strong&gt;Playground&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi55cpue7wxypd7qgctol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi55cpue7wxypd7qgctol.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Obtain GPUStack Model Access Information
&lt;/h1&gt;

&lt;p&gt;Open the &lt;strong&gt;Routes&lt;/strong&gt; page from the sidebar.&lt;/p&gt;

&lt;p&gt;Click the three-dot menu next to the &lt;strong&gt;Route&lt;/strong&gt;, then select:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API Access Info&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgko0djpn61kr0az0w5cj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgko0djpn61kr0az0w5cj.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Record the following information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Base URL
Model Name
API Key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Base URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://192.168.50.14/v1&lt;/span&gt;

&lt;span class="na"&gt;Model Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="s"&gt;qwen3.5-35b-a3b&lt;/span&gt;
&lt;span class="s"&gt;qwen3-reranker-4b&lt;/span&gt;
&lt;span class="s"&gt;qwen3-embedding-4b&lt;/span&gt;

&lt;span class="na"&gt;API Key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="s"&gt;gpustack_xxxxxxxxxxxxxxxxx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can create an API Key following the instructions in the UI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Deploy MaxKB
&lt;/h1&gt;

&lt;p&gt;MaxKB supports one-command Docker deployment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;maxkb &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="nt"&gt;-v&lt;/span&gt; ~/.maxkb:/opt/maxkb 1panel/maxkb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Default credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;admin / MaxKB@123..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foa0b22cjnz5xnqbpwppz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foa0b22cjnz5xnqbpwppz.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Upon first login, you will be prompted to change the password.&lt;/p&gt;

&lt;p&gt;Follow the instructions to update it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Connect GPUStack Models in MaxKB
&lt;/h1&gt;

&lt;p&gt;In the top navigation bar of MaxKB, select &lt;strong&gt;Model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faw5legtdwqovc6ew4ot9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faw5legtdwqovc6ew4ot9.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Add Model&lt;/strong&gt; in the upper-right corner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgf9gjxldkjccok6rrgnn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgf9gjxldkjccok6rrgnn.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qt03j6jobfzic92lrkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qt03j6jobfzic92lrkg.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fza2zo78gz8nzhnmfjtya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fza2zo78gz8nzhnmfjtya.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;API URL&lt;/code&gt; and &lt;code&gt;API Key&lt;/code&gt; will only appear &lt;strong&gt;after entering the Base Model and pressing Enter&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Add the following models in the same way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;qwen3-reranker-4b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;qwen3-embedding-4b&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;strong&gt;qwen3-reranker-4b&lt;/strong&gt;, you must enable &lt;strong&gt;Generic Proxy&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fop06mr01gctdps0cn8c4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fop06mr01gctdps0cn8c4.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is because MaxKB uses the endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/v2/rerank
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenpohberig3rmu39qpte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenpohberig3rmu39qpte.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77amye6pqwm8aynpeoz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F77amye6pqwm8aynpeoz7.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After configuration, it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgn82lhbdr3397lmpboj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgn82lhbdr3397lmpboj0.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Practical Example: Build a GPUStack Documentation Knowledge Base
&lt;/h1&gt;

&lt;p&gt;Open the &lt;strong&gt;Knowledge&lt;/strong&gt; page at the top and click &lt;strong&gt;Create&lt;/strong&gt; to create a knowledge base.&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;Web Knowledge&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni7ihbj48zje2qipvzjm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fni7ihbj48zje2qipvzjm.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the GPUStack documentation URL.&lt;/p&gt;

&lt;p&gt;MaxKB will automatically crawl and parse the page content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg3xdydqa7skt7a2etz2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsg3xdydqa7skt7a2etz2.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After crawling is complete:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr970a2psqyfex4cmyw2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr970a2psqyfex4cmyw2a.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create an AI Agent
&lt;/h2&gt;

&lt;p&gt;Go to the &lt;strong&gt;Agent&lt;/strong&gt; page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1z9av15o7qwzinsrl17u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1z9av15o7qwzinsrl17u.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt; to create a new Agent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs1echpbcfc4n3coi806.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgs1echpbcfc4n3coi806.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After completing the configuration, click &lt;strong&gt;Publish&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once published successfully, you can start chatting with the agent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxtxx29184mfdv3r0lar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxtxx29184mfdv3r0lar.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Chat Demo
&lt;/h2&gt;

&lt;p&gt;Open the chat interface:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F333brb860bzvlckvkeaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F333brb860bzvlckvkeaj.png" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71gkas76tl05mx7m33q5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71gkas76tl05mx7m33q5.png" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  🙌 Join the GPUStack Community
&lt;/h1&gt;

&lt;p&gt;If you have already started using GPUStack,&lt;br&gt;
or are exploring &lt;strong&gt;local large models / GPU resource management / AI infrastructure&lt;/strong&gt;,&lt;br&gt;
you are welcome to join our community group to exchange practical experience, pitfalls, and best practices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://discord.gg/QAzGncGs" rel="noopener noreferrer"&gt;https://discord.gg/QAzGncGs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
    </item>
    <item>
      <title>No More Token Anxiety: Build an “Unlimited-Use” Local AI Assistant with GPUStack + OpenClaw</title>
      <dc:creator>GPUStack</dc:creator>
      <pubDate>Fri, 06 Mar 2026 02:32:29 +0000</pubDate>
      <link>https://dev.to/gpustack/no-more-token-anxiety-build-an-unlimited-use-local-ai-assistant-with-gpustack-openclaw-5de6</link>
      <guid>https://dev.to/gpustack/no-more-token-anxiety-build-an-unlimited-use-local-ai-assistant-with-gpustack-openclaw-5de6</guid>
      <description>&lt;p&gt;Over the past two years, more and more teams have integrated AI into their daily workflows.&lt;br&gt;
But soon, a practical issue emerged:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The more the model is used, the faster Tokens are consumed, and both costs and psychological pressure rise accordingly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many people rely on AI to improve efficiency, while at the same time having to “use it sparingly” and “let it think less.”&lt;br&gt;
In the end, AI instead becomes a carefully budgeted consumable.&lt;/p&gt;

&lt;p&gt;If AI can run on your own GPU,&lt;br&gt;
&lt;strong&gt;without being billed by Token, available for conversation at any time, and running long-term inside collaboration tools,&lt;/strong&gt;&lt;br&gt;
then it truly feels like a real “work assistant.”&lt;/p&gt;

&lt;p&gt;Based on the local model capabilities provided by GPUStack, combined with &lt;strong&gt;OpenClaw (supporting multiple collaboration platforms such as WhatsApp, Telegram, Discord, Slack, Lark, etc.)&lt;/strong&gt; and Telegram,&lt;br&gt;
this article will walk through step by step how to build a &lt;strong&gt;truly usable, sustainably running, and almost Token-worry-free&lt;/strong&gt; local AI assistant.&lt;/p&gt;
&lt;h2&gt;
  
  
  📌 What This Article Covers
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Deploying a model with GPUStack&lt;/li&gt;
&lt;li&gt;Creating a Telegram bot application and configuring permissions&lt;/li&gt;
&lt;li&gt;Installing, configuring, and key considerations for OpenClaw&lt;/li&gt;
&lt;li&gt;First-time authorization and connectivity testing on the Telegram side&lt;/li&gt;
&lt;li&gt;Practical example: Let the assistant star the GPUStack project&lt;/li&gt;
&lt;li&gt;Built-in assistant commands&lt;/li&gt;
&lt;li&gt;Useful OpenClaw commands and resource links&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  I. Deploy a Model with GPUStack and Prepare Access Information
&lt;/h2&gt;

&lt;p&gt;Before connecting OpenClaw, we need to complete model deployment in &lt;strong&gt;GPUStack&lt;/strong&gt; and obtain the model service access information.&lt;/p&gt;

&lt;p&gt;This section will use &lt;strong&gt;Qwen3.5-35B-A3B&lt;/strong&gt; as an example to demonstrate the complete process from&lt;br&gt;
&lt;strong&gt;Custom inference backend → Deploy model → Obtain access information&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Environment Preparation and Version Information
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GPUStack version: &lt;strong&gt;v2.0.3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Custom inference backend image:
&lt;code&gt;vllm/vllm-openai:qwen3_5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Model weights: &lt;strong&gt;Qwen/Qwen3.5-35B-A3B&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ OpenClaw has requirements for the model context window:&lt;br&gt;
&lt;strong&gt;Minimum 16K, recommended 128K or above&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  2. Configure Custom Inference Backend (vLLM)
&lt;/h3&gt;

&lt;p&gt;In the GPUStack console, go to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Inference Backends” → “Edit vLLM” → “Add Version”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4n50a6nmswapd37g55ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4n50a6nmswapd37g55ys.png" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Deploy the Qwen3.5-35B-A3B Model
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ckvjnb5qu8z5ln5dc9l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ckvjnb5qu8z5ln5dc9l.png" width="793" height="219"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F926wc9o61drenbfjx5hs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F926wc9o61drenbfjx5hs.png" width="770" height="1053"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Example parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--tensor-parallel-size=2
--mm-encoder-tp-mode data
--mm-processor-cache-type shm
--reasoning-parser qwen3
--enable-auto-tool-choice
--tool-call-parser qwen3_coder
--speculative-config '{"method": "mtp", "num_speculative_tokens": 1}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;If you encounter:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;text&lt;br&gt;
Error 803: system has unsupported display driver / cuda driver combination&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can try adding the environment variable:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
LD_LIBRARY_PATH=/usr/local/nvidia/lib64:/usr/local/nvidia/lib:/usr/lib/x86_64-linux-gnu&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Obtain GPUStack Model Access Information
&lt;/h3&gt;

&lt;p&gt;Record the following three items:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API Base URL&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Model ID&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Key&lt;/strong&gt; (create it in GPUStack)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r1i3skvqvc9rlf983qz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9r1i3skvqvc9rlf983qz.png" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  II. Create a Telegram Bot
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open Telegram and search for &lt;strong&gt;BotFather&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the &lt;strong&gt;BotFather&lt;/strong&gt; APP&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fausk5tydr18bj791dt5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fausk5tydr18bj791dt5y.png" width="584" height="938"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new Bot and fill in the basic information&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fzp5sjbum5wsfr569me.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fzp5sjbum5wsfr569me.png" width="602" height="1068"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5arofy5sjknqcdbtbmhe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5arofy5sjknqcdbtbmhe.png" width="602" height="1068"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the &lt;strong&gt;Bot Token&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqz02jt86iacxqefqbmij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqz02jt86iacxqefqbmij.png" width="602" height="1068"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For details, please refer to: &lt;a href="https://docs.openclaw.ai/channels/telegram" rel="noopener noreferrer"&gt;https://docs.openclaw.ai/channels/telegram&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  III. Install and Configure OpenClaw
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Demo environment: Ubuntu 24.04&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  1. One-Click Installation
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
curl -fsSL https://openclaw.ai/install.sh | bash&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The script will automatically install dependencies such as Node and Git.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rwhwbw5sb7lipqwfx2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6rwhwbw5sb7lipqwfx2c.png" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Interactive Configuration Wizard
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model/Auth Provider&lt;/strong&gt;
Select &lt;code&gt;Custom Provider (Any OpenAI or Anthropic compatible endpoint)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlvp9qjyo0us9mqdr4uv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlvp9qjyo0us9mqdr4uv.png" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter the GPUStack &lt;strong&gt;API Base URL / API Key&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mnlmvja8d5ymthuawt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5mnlmvja8d5ymthuawt9.png" width="800" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;code&gt;Telegram&lt;/code&gt; for &lt;strong&gt;Channel&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5q3ms06a38jcg00jhxfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5q3ms06a38jcg00jhxfu.png" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paste the &lt;strong&gt;Bot Token&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawtd0sp933q1vb14zf0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawtd0sp933q1vb14zf0w.png" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  IV. First-Time Authorization and Testing
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Send a message to the bot in Telegram&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On first use, it will prompt for &lt;strong&gt;Pairing authorization&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno3ttqkzm8zuauz1yckv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno3ttqkzm8zuauz1yckv.png" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On the server, run:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
   openclaw pairing approve telegram &amp;lt;Pairing-Code&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2vy065y262m9kdb82k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka2vy065y262m9kdb82k.png" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  V. Practical Example: Let the Bot Star the GPUStack Project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Prepare a GitHub PAT
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;Tokens (classic)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Check the &lt;code&gt;repo&lt;/code&gt; permission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq51fy4dnqb4b2fb0bal5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq51fy4dnqb4b2fb0bal5.png" alt="GitHub PAT" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Write to Environment Variables
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
vim ~/.openclaw/.env&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwkl5b2char6p6t3xz6z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwkl5b2char6p6t3xz6z.png" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Restart:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
openclaw gateway restart&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Send a Command to the Bot
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwg9cysmqnb18lq44nklr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwg9cysmqnb18lq44nklr.png" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiy9x4dn3ino6r2xtlyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiiy9x4dn3ino6r2xtlyh.png" width="800" height="725"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  VI. Common Commands
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/new&lt;/code&gt;: Start a new session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/status&lt;/code&gt;: Check bot status&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/reset&lt;/code&gt;: Reset context&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/model&lt;/code&gt;: View / switch model&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  VII. Useful OpenClaw Commands and Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common CLI Commands
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
openclaw logs --follow&lt;br&gt;
openclaw doctor&lt;br&gt;
openclaw gateway --help&lt;br&gt;
openclaw dashboard&lt;br&gt;
openclaw tui&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Documentation and Ecosystem
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📘 &lt;a href="https://docs.openclaw.ai" rel="noopener noreferrer"&gt;https://docs.openclaw.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;a href="https://clawhub.ai" rel="noopener noreferrer"&gt;https://clawhub.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion: When AI Becomes Infrastructure, Not a Consumable
&lt;/h2&gt;

&lt;p&gt;Looking back, &lt;strong&gt;the essence of Token anxiety is not that models are expensive, but that AI is treated as an “external consumable resource.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When models run in the cloud and capabilities are controlled by others,&lt;br&gt;
we become accustomed to careful budgeting, limiting usage, and controlling call frequency.&lt;/p&gt;

&lt;p&gt;But when the model truly runs on your own GPU,&lt;br&gt;
when inference capability, context, and tool calls all become part of your infrastructure,&lt;br&gt;
the role of AI changes accordingly—&lt;/p&gt;

&lt;p&gt;It is no longer a paid API call each time,&lt;br&gt;
but a &lt;strong&gt;readily available, long-term online, continuously evolving work assistant&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is exactly the significance of combining GPUStack and OpenClaw:&lt;br&gt;
&lt;strong&gt;Let AI return from a “cost item” to “productivity.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you already have GPU resources,&lt;br&gt;
you might as well try it yourself and truly integrate AI into your daily workflow.&lt;/p&gt;

&lt;p&gt;When you no longer worry about Tokens,&lt;br&gt;
you will truly begin to make good use of AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  🙌 Join the GPUStack Community
&lt;/h2&gt;

&lt;p&gt;If you have already started using GPUStack,&lt;br&gt;
or are exploring &lt;strong&gt;local large models / GPU resource management / AI Infra&lt;/strong&gt;,&lt;br&gt;
you are welcome to join our community group to exchange practical experience, pitfalls, and best practices together.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://discord.gg/QAzGncGs" rel="noopener noreferrer"&gt;https://discord.gg/QAzGncGs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gpustack</category>
      <category>openclaw</category>
      <category>ai</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
