<?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: Ecohash</title>
    <description>The latest articles on DEV Community by Ecohash (@ecohash).</description>
    <link>https://dev.to/ecohash</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%2F4135137%2F71d3fea4-9cb8-4d81-8a72-81f498d3d21a.png</url>
      <title>DEV Community: Ecohash</title>
      <link>https://dev.to/ecohash</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ecohash"/>
    <language>en</language>
    <item>
      <title>Best models to run on RTX Pro 6000 96GB</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Sun, 01 Nov 2026 11:55:46 +0000</pubDate>
      <link>https://dev.to/ecohash/best-models-to-run-on-rtx-pro-6000-96gb-387b</link>
      <guid>https://dev.to/ecohash/best-models-to-run-on-rtx-pro-6000-96gb-387b</guid>
      <description>&lt;p&gt;The right model depends on the task, not on the GPU. A 96 GB RTX Pro 6000 holds a 20B to 35B open model with room for context and batching, so you get to pick by the job instead of by a memory ceiling. For coding and agents that means Qwen3 Coder 30B; for low-cost chat, gpt-oss 20B; for retrieval, an embedding model with a reranker; for voice, Whisper and Kokoro. All of them run through the same OpenAI-compatible API at &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;, so you start on the shared API and move to a dedicated endpoint or a workspace later without touching your code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pick by task, not by memory.&lt;/strong&gt; Coding: &lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;. Chat: &lt;code&gt;gpt-oss-20b&lt;/code&gt;. Retrieval: &lt;code&gt;jina-embeddings-v3&lt;/code&gt; + &lt;code&gt;bge-reranker-v2-m3&lt;/code&gt;. Voice: &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; + &lt;code&gt;kokoro-82m&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Model by task
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coding, agents, tool use&lt;/strong&gt; · Model on EcoHash: Qwen3 Coder 30B · Model ID: &lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;General chat, low cost&lt;/strong&gt; · Model on EcoHash: gpt-oss 20B · Model ID: &lt;code&gt;gpt-oss-20b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;General chat, higher capability&lt;/strong&gt; · Model on EcoHash: GLM 5.2, DeepSeek V4 Flash · Model ID: &lt;code&gt;GLM-5.2&lt;/code&gt;, &lt;code&gt;DeepSeek-V4-Flash&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embeddings for RAG&lt;/strong&gt; · Model on EcoHash: Jina v3, Qwen3 Embedding · Model ID: &lt;code&gt;jina-embeddings-v3&lt;/code&gt;, &lt;code&gt;qwen3-embedding-8b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reranking for RAG&lt;/strong&gt; · Model on EcoHash: BGE reranker v2 m3 · Model ID: &lt;code&gt;bge-reranker-v2-m3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech to text&lt;/strong&gt; · Model on EcoHash: Whisper Large V3 Turbo · Model ID: &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text to speech&lt;/strong&gt; · Model on EcoHash: Kokoro 82M · Model ID: &lt;code&gt;kokoro-82m&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The higher-capability chat models run through the hosted API, not on a single 96 GB card. Here is what the single-card models measure on EcoHash, end-to-end, in July 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coding&lt;/strong&gt; · Model: &lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt; · Measured on EcoHash: 30 ms TTFT, ~110 tok/s, 32k context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;General chat&lt;/strong&gt; · Model: &lt;code&gt;gpt-oss-20b&lt;/code&gt; · Measured on EcoHash: 170 ms TTFT, ~125 tok/s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;General chat&lt;/strong&gt; · Model: &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt; · Measured on EcoHash: 205 ms TTFT, ~143 tok/s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech to text&lt;/strong&gt; · Model: &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; · Measured on EcoHash: WER 4.37, ~0.5 s per 10 s of audio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text to speech&lt;/strong&gt; · Model: &lt;code&gt;kokoro-82m&lt;/code&gt; · Measured on EcoHash: first audio ~120 ms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Against other providers of the same open models, EcoHash serves them at full BF16 precision and lands competitively on price and speed (&lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;, EcoHash in purple):&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%2F3qkji4zd2xbkf173zdn3.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%2F3qkji4zd2xbkf173zdn3.png" alt="Llama-3.1-8B price vs speed: EcoHash vs peers" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full data and charts: &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks" rel="noopener noreferrer"&gt;ecohash-benchmarks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPU:&lt;/strong&gt; NVIDIA RTX Pro 6000 Blackwell Server Edition, 96 GB GDDR7&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single-card sweet spot:&lt;/strong&gt; 20B to 35B open models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API base URL:&lt;/strong&gt; &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access:&lt;/strong&gt; Shared API, dedicated endpoint, GPU workspace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Price:&lt;/strong&gt; RTX Pro 6000 at $1.89 per GPU-hour (&lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;/pricing&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Developers choosing an open model for a coding, chat, retrieval, or voice feature.&lt;/li&gt;
&lt;li&gt;Teams deciding what to run on a 96 GB card versus what to call through a hosted API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you can decide
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Which model to start with for your task.&lt;/li&gt;
&lt;li&gt;Whether it fits on a single RTX Pro 6000 or is better used through the hosted API.&lt;/li&gt;
&lt;li&gt;When to move from the shared API to a dedicated endpoint or a workspace.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to choose
&lt;/h2&gt;

&lt;p&gt;Four questions get you most of the way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the task? Code, chat, retrieval, or speech. Start here, not with the hardware.&lt;/li&gt;
&lt;li&gt;Does it fit in 96 GB at your context length and batch size? A 20B to 35B model fits with room to spare, models near 70B need quantization, and 235B and up are better through the hosted API.&lt;/li&gt;
&lt;li&gt;What are your latency and throughput needs? Steady, high-volume traffic is the reason to reserve a dedicated endpoint.&lt;/li&gt;
&lt;li&gt;Do you need to self-host at all? For most teams the shared API is enough, and the GPU is EcoHash's problem, not yours.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Coding
&lt;/h2&gt;

&lt;p&gt;Qwen3 Coder 30B (&lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;) is the default for code generation, refactoring, and tool-using agents. It is a Mixture-of-Experts model with about 30B total parameters, it fits comfortably on one 96 GB card, and on EcoHash it serves a 32,768-token context at about 110 tokens/sec single-stream with a 30 ms time to first token. See &lt;a href="https://ecohash.com/models/qwen3-coder-30b-a3b-instruct" rel="noopener noreferrer"&gt;/models/qwen3-coder-30b-a3b-instruct&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For lighter or cheaper high-volume coding, gpt-oss 20B (&lt;code&gt;gpt-oss-20b&lt;/code&gt;) is the smaller option. The three deployment paths for Qwen3 Coder are covered in &lt;a href="https://ecohash.com/blog/qwen3-coder-30b-rtx-pro-6000" rel="noopener noreferrer"&gt;Qwen3 Coder 30B on RTX Pro 6000&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  General chat
&lt;/h2&gt;

&lt;p&gt;Start with gpt-oss 20B (&lt;code&gt;gpt-oss-20b&lt;/code&gt;) for low-cost chat and assistants. It fits on one card, has a long context, and reaches about 8,900 output tokens/sec under load.&lt;/p&gt;

&lt;p&gt;For stronger general capability, EcoHash also serves larger models such as GLM 5.2 (&lt;code&gt;GLM-5.2&lt;/code&gt;) and DeepSeek V4 Flash (&lt;code&gt;DeepSeek-V4-Flash&lt;/code&gt;), and very large Mixture-of-Experts models like Qwen3-235B-A22B (&lt;code&gt;Qwen3-235B-A22B&lt;/code&gt;). Those are not single-card deployments. Use them through the shared API or a dedicated endpoint and let EcoHash handle the hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retrieval (RAG)
&lt;/h2&gt;

&lt;p&gt;A retrieval pipeline needs two models: an embedding model to index and search text, and a reranker to reorder the top results.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embeddings: &lt;code&gt;jina-embeddings-v3&lt;/code&gt;, &lt;code&gt;jina-embeddings-v4&lt;/code&gt;, or the Qwen3 Embedding family (&lt;code&gt;qwen3-embedding-8b&lt;/code&gt;, &lt;code&gt;qwen3-embedding-4b&lt;/code&gt;, &lt;code&gt;qwen3-embedding-0.6b&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Reranking: &lt;code&gt;bge-reranker-v2-m3&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of them run through the same key, so one service can embed, rerank, and generate the answer without stitching vendors together. See the &lt;a href="https://ecohash.com/use-cases/rag" rel="noopener noreferrer"&gt;RAG use case&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Voice
&lt;/h2&gt;

&lt;p&gt;A voice agent uses three model types: speech to text, a chat model, and text to speech.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speech to text: &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; or &lt;code&gt;qwen3-asr-1-7b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Text to speech: &lt;code&gt;kokoro-82m&lt;/code&gt; or &lt;code&gt;qwen3-tts&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These speech models are small and do not need an RTX Pro 6000. They run through the API and move onto GPU capacity only when throughput grows. The full build is in &lt;a href="https://ecohash.com/blog/kokoro-whisper-voice-agent" rel="noopener noreferrer"&gt;Build a voice agent with Whisper, Kokoro, and an OpenAI-compatible API&lt;/a&gt;; see also &lt;a href="https://ecohash.com/use-cases/voice-speech" rel="noopener noreferrer"&gt;/use-cases/voice-speech&lt;/a&gt;, &lt;a href="https://ecohash.com/models/kokoro-82m" rel="noopener noreferrer"&gt;/models/kokoro-82m&lt;/a&gt;, and &lt;a href="https://ecohash.com/models/whisper-large-v3-turbo" rel="noopener noreferrer"&gt;/models/whisper-large-v3-turbo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling these models
&lt;/h2&gt;

&lt;p&gt;The API is OpenAI-compatible. A coding call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.ecohash.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eco_...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qwen3-coder-30b-a3b-instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Refactor this to be iterative:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;def fib(n):&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;    return n if n &amp;lt; 2 else fib(n-1) + fib(n-2)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An embeddings call for a RAG index:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;emb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jina-embeddings-v3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EcoHash serves open models through an OpenAI-compatible API.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Shared API, dedicated endpoint, or workspace
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Shared API: no GPU to manage, pay per token, good for building and variable traffic. See &lt;a href="https://ecohash.com/inference" rel="noopener noreferrer"&gt;/inference&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Dedicated endpoint: reserved capacity for one model, steadier throughput and more predictable latency. See &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;/dedicated-inference&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;GPU workspace: an hourly RTX Pro 6000 for experiments, fine-tuning, and batch jobs. See &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;/gpu-compute&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Model fit depends on quantization, context length, and batch size. The ranges here are starting points to validate, not guarantees.&lt;/li&gt;
&lt;li&gt;The higher-capability chat models are for the hosted API, not single-card serving.&lt;/li&gt;
&lt;li&gt;Real performance depends on your setup. Reproduce any figure with its method and date.&lt;/li&gt;
&lt;li&gt;Model IDs change as the catalog changes. Check &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;/models&lt;/a&gt; before you build.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is the best model to run on an RTX Pro 6000 96GB?&lt;/strong&gt; It depends on the task. Coding: &lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;. General chat: &lt;code&gt;gpt-oss-20b&lt;/code&gt;. Retrieval: &lt;code&gt;jina-embeddings-v3&lt;/code&gt; with &lt;code&gt;bge-reranker-v2-m3&lt;/code&gt;. Speech: &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; with &lt;code&gt;kokoro-82m&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the best coding model for the RTX Pro 6000?&lt;/strong&gt; Qwen3 Coder 30B (&lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;). It fits on one 96 GB card and serves a 32,768-token context on EcoHash.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a good low-cost general chat model?&lt;/strong&gt; gpt-oss 20B (&lt;code&gt;gpt-oss-20b&lt;/code&gt;). It fits on one card and has a long context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I run a 235B model on one RTX Pro 6000?&lt;/strong&gt; No. Use a model like &lt;code&gt;Qwen3-235B-A22B&lt;/code&gt; through the hosted API instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What models do I need for RAG?&lt;/strong&gt; An embedding model and a reranker, for example &lt;code&gt;jina-embeddings-v3&lt;/code&gt; and &lt;code&gt;bge-reranker-v2-m3&lt;/code&gt;, plus a chat model to write the answer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do speech models need an RTX Pro 6000?&lt;/strong&gt; No. Whisper and Kokoro run through the API, and move onto GPU capacity only when throughput demands it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How many models can I use with one API key?&lt;/strong&gt; All of them. Every model shares one key and one base URL, &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does this cost?&lt;/strong&gt; API usage is billed per token; a GPU workspace runs at $1.89 per GPU-hour. See &lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;/pricing&lt;/a&gt; for current rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Browse all models: &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;/models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;See the RTX Pro 6000 page: &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;/gpu-compute&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reserve capacity: &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;/dedicated-inference&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
    </item>
    <item>
      <title>LTX 2.5 on One RTX PRO 6000: A 10-Second 1080p Video With Audio in 90 Seconds</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Sat, 31 Oct 2026 16:08:53 +0000</pubDate>
      <link>https://dev.to/ecohash/ltx-25-on-one-rtx-pro-6000-a-10-second-1080p-video-with-audio-in-90-seconds-3ki5</link>
      <guid>https://dev.to/ecohash/ltx-25-on-one-rtx-pro-6000-a-10-second-1080p-video-with-audio-in-90-seconds-3ki5</guid>
      <description>&lt;p&gt;On October 27, 2026 we launched the public &lt;strong&gt;LTX 2.5 Video Generation&lt;/strong&gt; template on one NVIDIA RTX PRO 6000 Blackwell Server Edition (96 GB). We had Claude Opus 5.5 do the launch through the EcoHash GPU MCP server and write the prompts. Then we timed 24 renders across four output sizes and three clip lengths. Every render included a generated soundtrack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; EcoHash operates the platform and the template tested here. This is our own measurement on a standard on-demand instance from the public Console catalogue, not an independent review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results at a glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measurement (one RTX PRO 6000, warm server, 24 fps, audio on)&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;Launch call → &lt;code&gt;/health&lt;/code&gt; ready&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;3 min 10 s&lt;/strong&gt; (instance running at 1 min 33 s; the rest is loading 72.9 GiB of weights)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First request after start (2 s, 768×512)&lt;/td&gt;
&lt;td&gt;6.0 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 s clip at 1080p (1920×1088)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;90.0 s&lt;/strong&gt; (9.0× real time)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 s clip at 720p (1280×704)&lt;/td&gt;
&lt;td&gt;33.6 s (3.4× real time)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 s clip at 480p (768×512)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;14.8 s&lt;/strong&gt; (1.5× real time)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 s 1080p clips per GPU-hour, sequential&lt;/td&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same seed, same request&lt;/td&gt;
&lt;td&gt;Byte-identical mp4 on every repeat&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How long does LTX 2.5 take per clip on an RTX PRO 6000?
&lt;/h2&gt;

&lt;p&gt;Mean wall time per clip, two runs each, measured from the client. The figure includes the two-stage diffusion, VAE decode, audio muxing and returning the file.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Resolution&lt;/th&gt;
&lt;th&gt;Clip&lt;/th&gt;
&lt;th&gt;Runs&lt;/th&gt;
&lt;th&gt;Wall time (mean)&lt;/th&gt;
&lt;th&gt;× real time&lt;/th&gt;
&lt;th&gt;Clips / GPU-hour&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;480p 3:2&lt;/td&gt;
&lt;td&gt;768×512&lt;/td&gt;
&lt;td&gt;2 s (49 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5.1 s&lt;/td&gt;
&lt;td&gt;2.5×&lt;/td&gt;
&lt;td&gt;700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;480p 3:2&lt;/td&gt;
&lt;td&gt;768×512&lt;/td&gt;
&lt;td&gt;5 s (121 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8.9 s&lt;/td&gt;
&lt;td&gt;1.8×&lt;/td&gt;
&lt;td&gt;405&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;480p 3:2&lt;/td&gt;
&lt;td&gt;768×512&lt;/td&gt;
&lt;td&gt;10 s (241 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;14.8 s&lt;/td&gt;
&lt;td&gt;1.5×&lt;/td&gt;
&lt;td&gt;243&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;720p 16:9&lt;/td&gt;
&lt;td&gt;1280×704&lt;/td&gt;
&lt;td&gt;2 s (49 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8.4 s&lt;/td&gt;
&lt;td&gt;4.1×&lt;/td&gt;
&lt;td&gt;427&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;720p 16:9&lt;/td&gt;
&lt;td&gt;1280×704&lt;/td&gt;
&lt;td&gt;5 s (121 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;16.9 s&lt;/td&gt;
&lt;td&gt;3.4×&lt;/td&gt;
&lt;td&gt;213&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;720p 16:9&lt;/td&gt;
&lt;td&gt;1280×704&lt;/td&gt;
&lt;td&gt;10 s (241 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;33.6 s&lt;/td&gt;
&lt;td&gt;3.4×&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1080p 16:9&lt;/td&gt;
&lt;td&gt;1920×1088&lt;/td&gt;
&lt;td&gt;2 s (49 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;16.8 s&lt;/td&gt;
&lt;td&gt;8.2×&lt;/td&gt;
&lt;td&gt;214&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1080p 16:9&lt;/td&gt;
&lt;td&gt;1920×1088&lt;/td&gt;
&lt;td&gt;5 s (121 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;40.5 s&lt;/td&gt;
&lt;td&gt;8.0×&lt;/td&gt;
&lt;td&gt;88&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1080p 16:9&lt;/td&gt;
&lt;td&gt;1920×1088&lt;/td&gt;
&lt;td&gt;10 s (241 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;90.0 s&lt;/td&gt;
&lt;td&gt;9.0×&lt;/td&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1080p 9:16&lt;/td&gt;
&lt;td&gt;1088×1920&lt;/td&gt;
&lt;td&gt;2 s (49 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;16.7 s&lt;/td&gt;
&lt;td&gt;8.2×&lt;/td&gt;
&lt;td&gt;215&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1080p 9:16&lt;/td&gt;
&lt;td&gt;1088×1920&lt;/td&gt;
&lt;td&gt;5 s (121 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;41.8 s&lt;/td&gt;
&lt;td&gt;8.3×&lt;/td&gt;
&lt;td&gt;86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1080p 9:16&lt;/td&gt;
&lt;td&gt;1088×1920&lt;/td&gt;
&lt;td&gt;10 s (241 frames)&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;118–194 s*&lt;/td&gt;
&lt;td&gt;11.8×&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At 1080p, render time grows roughly in proportion to clip length: 16.8 s for 2 s of video, 40.5 s for 5 s and 90.0 s for 10 s. For 2 s and 5 s clips, portrait 1088×1920 matched landscape within 1.3 s. At 10 s, the faster portrait run took 118 s, 28 s slower than landscape.&lt;/p&gt;

&lt;p&gt;* The two portrait 10 s runs took 118 s and 194 s. During the slower one, the GPU logged about 75 s at near-zero utilization while our SSH tunnel stopped answering &lt;code&gt;/health&lt;/code&gt;. That points to transfer, not generation. The rate columns therefore use the 118 s run.&lt;/p&gt;

&lt;p&gt;In the other eleven cells, two runs of the same request differed by at most 1.0 s. In all twelve, the two output files were byte-identical.&lt;/p&gt;

&lt;h2&gt;
  
  
  How fast does the LTX 2.5 template start?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;Time after &lt;code&gt;launch_template&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Instance &lt;code&gt;running&lt;/code&gt;, SSH ready&lt;/td&gt;
&lt;td&gt;1 min 33 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/health&lt;/code&gt; returns &lt;code&gt;{"status":"ready"}&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;≤ 3 min 10 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First 2-second test clip returned&lt;/td&gt;
&lt;td&gt;+ 6.0 s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You don't download or install anything. The template mounts the LTX 2.5 Diffusers weights read-only from shared storage and starts a FastAPI server on port 8000.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does a clip cost on a rented RTX PRO 6000?
&lt;/h2&gt;

&lt;p&gt;A GPU instance is billed per hour while it runs, not per clip, so the useful number is clips per GPU-hour. Multiply by the current RTX PRO 6000 hourly rate on the &lt;a href="https://ecohash.com/gpu/rtx-pro-6000" rel="noopener noreferrer"&gt;RTX PRO 6000 page&lt;/a&gt; to get a cost per clip.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;10 s clips per GPU-hour (sequential)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;480p&lt;/td&gt;
&lt;td&gt;243&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;720p&lt;/td&gt;
&lt;td&gt;107&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1080p&lt;/td&gt;
&lt;td&gt;39&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two things move the real number:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Idle time.&lt;/strong&gt; The instance bills whether or not it is rendering. Our session was billed for 4 h 41 min, but the GPU log shows it was busy (≥ 10% utilization) for only 23 minutes. The rest was idle time while our client was disconnected. Terminate as soon as you are done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries.&lt;/strong&gt; We kept 6 of 8 shots on the first take. Budget for at least one extra take per shot you intend to keep.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do you run LTX 2.5 with Claude and the EcoHash GPU MCP?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Connect&lt;/strong&gt; the EcoHash GPU MCP server to Claude (&lt;a href="https://docs.ecohash.com/api-reference/gpu-mcp" rel="noopener noreferrer"&gt;setup guide&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Launch.&lt;/strong&gt; Ask Claude to start the "LTX 2.5 Video Generation" template. It calls &lt;code&gt;list_templates&lt;/code&gt;, then &lt;code&gt;quote_template&lt;/code&gt;, waits for your confirmation, then calls &lt;code&gt;launch_template&lt;/code&gt;. Pass your SSH public key if you want a shell.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait&lt;/strong&gt; for &lt;code&gt;get_instance&lt;/code&gt; to report &lt;code&gt;running&lt;/code&gt;, then poll &lt;code&gt;GET /health&lt;/code&gt; until it returns &lt;code&gt;ready&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt.&lt;/strong&gt; Have Claude write one prompt per shot in five parts: camera, subject, one action with a visible result, an ending, and the sound.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render.&lt;/strong&gt; Call &lt;code&gt;POST /v1/video/generations&lt;/code&gt; with &lt;code&gt;prompt&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;num_frames&lt;/code&gt;, &lt;code&gt;fps&lt;/code&gt; and &lt;code&gt;seed&lt;/code&gt;. The response holds the mp4 with audio as base64.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminate&lt;/strong&gt; with &lt;code&gt;terminate_instance&lt;/code&gt; once your files are saved locally, because the scratch disk is deleted with the instance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A minimal request:&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/video/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;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"prompt":"Doorbell camera footage at night on Halloween ... Audio: crinkling candy wrappers, distant crickets. No music, no speech.",
       "width":1920,"height":1088,"num_frames":241,"fps":24,"seed":20261027}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | python3 &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"import sys,json,base64;open('out.mp4','wb').write(base64.b64decode(json.load(sys.stdin)['data'][0]['b64_mp4']))"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Width and height are rounded to multiples of 32, so 1080 becomes 1088. &lt;code&gt;num_frames&lt;/code&gt; is rounded to 8k+1, and 241 frames at 24 fps is about 10 seconds. The server runs the distilled two-stage schedule (8 + 3 sigmas, unguided). It accepts &lt;code&gt;num_inference_steps&lt;/code&gt; and &lt;code&gt;guidance_scale&lt;/code&gt; but ignores them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which prompt structure worked best?
&lt;/h2&gt;

&lt;p&gt;We gave Claude a one-line brief: a Halloween-week variant of the "caught on a doorbell camera" format, with eight 16:9 shots. We asked for each prompt in five parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[camera / footage type], [time + place]. [one subject doing one thing].
[one action with a visible result]. [ending: freeze or look into the lens].
Audio: [2–3 concrete sounds]. No music, no speech.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude then checked every prompt against four questions before we rendered anything:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is something happening in the first second?&lt;/li&gt;
&lt;li&gt;Is there only one action?&lt;/li&gt;
&lt;li&gt;Is there an ending?&lt;/li&gt;
&lt;li&gt;Can you hear the sound?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The camera phrase, such as "doorbell security camera footage" or "handheld phone video", did more for realism than any quality adjective.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did LTX 2.5 get wrong?
&lt;/h2&gt;

&lt;p&gt;We rendered eight 1080p shots, at 5 s or 8 s each, from Claude's prompts. On the first take we kept six. The misses are worth knowing before you write prompts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Objects vanish instead of falling.&lt;/strong&gt; We asked for a black cat to push a jack-o'-lantern off a railing. The cat never touched it, and the pumpkin simply disappeared.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readable text is gibberish.&lt;/strong&gt; A hand-lettered sign beside a candy bowl came out as invented words.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Words are taken literally.&lt;/strong&gt; "A great horned owl" produced an owl with actual horns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Counts drift.&lt;/strong&gt; We asked for five costumed raccoons and got four.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What worked well: fisheye "doorbell camera" framing, night-vision grain, animal fur and motion, and sound that matched the action, such as wrappers crinkling and a plastic bowl clattering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does the network path change the timing?
&lt;/h2&gt;

&lt;p&gt;Yes, so measure where you render. Called from inside the instance (&lt;code&gt;localhost:8000&lt;/code&gt;), an 8 s 1080p shot took 63.7–64.5 s and a 5 s 1080p shot took 36.3–36.9 s. Through our SSH tunnel, an earlier 8 s shot took 329 s, almost all of it transfer. The platform's public service URL returned 502 for requests that ran longer than about a minute. For long renders, run the request on the instance and copy the files back afterwards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test environment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GPU: 1 × NVIDIA RTX PRO 6000 Blackwell Server Edition, 96 GB, driver 580.105.08&lt;/li&gt;
&lt;li&gt;Template: EcoHash public template "LTX 2.5 Video Generation" (image &lt;code&gt;vllm/vllm-omni:v0.27.0rc1&lt;/code&gt;), Atlanta region&lt;/li&gt;
&lt;li&gt;Pipeline: Diffusers &lt;code&gt;LTX2Pipeline&lt;/code&gt;, distilled DiT, two-stage 8 + 3 sigma schedule, guidance 1.0, audio on&lt;/li&gt;
&lt;li&gt;Timing matrix: sequential requests through an SSH tunnel, client-side wall clock. Opening shots: sequential requests from inside the instance.&lt;/li&gt;
&lt;li&gt;Prompt for the timing matrix: a fixed Halloween porch scene, seed 20261027, 24 fps&lt;/li&gt;
&lt;li&gt;Date: October 27, 2026&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This is one GPU, one prompt for the timing matrix and two runs per cell. Other prompts may vary slightly in time; content does not change the step count.&lt;/li&gt;
&lt;li&gt;We did not test concurrent requests. The server holds a GPU lock and queues them.&lt;/li&gt;
&lt;li&gt;We did not test image-to-video timing, longer clips beyond 241 frames, or other runtimes.&lt;/li&gt;
&lt;li&gt;Clip quality is judged by eye. We report what we kept, not a quality score.&lt;/li&gt;
&lt;li&gt;LTX 2.5 is distributed under the LTX-2 Community License. Check its terms for your use case before you publish commercially.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can one RTX PRO 6000 render 1080p LTX 2.5 video?&lt;/strong&gt; Yes. A 10-second 1920×1088 clip with audio rendered in 90.0 s on a single 96 GB RTX PRO 6000. We used no CPU offload and no quantization flags.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does LTX 2.5 generate sound?&lt;/strong&gt; Yes. Every render in this test came back with an AAC soundtrack generated alongside the frames. Describe the sounds in an &lt;code&gt;Audio:&lt;/code&gt; sentence in the prompt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the output reproducible?&lt;/strong&gt; In our test it was. Repeating a request with the same seed produced byte-identical files in every one of the 12 size and length pairs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long until the template is usable?&lt;/strong&gt; In our test, &lt;code&gt;/health&lt;/code&gt; reported ready 3 min 10 s after the launch call. The first short render returned 6 s later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to download the model?&lt;/strong&gt; No. The template mounts the weights from shared storage. You pay only for the GPU time you run.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I work on EcoHash. This post was originally published on the &lt;a href="https://ecohash.com/blog/ltx-2-5-rtx-pro-6000-benchmark" rel="noopener noreferrer"&gt;EcoHash blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>deeplearning</category>
      <category>hardware</category>
      <category>performance</category>
    </item>
    <item>
      <title>Run DeepSeek V4 Flash Vision with an EcoHash GPU template</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Fri, 23 Oct 2026 05:40:01 +0000</pubDate>
      <link>https://dev.to/ecohash/run-deepseek-v4-flash-vision-with-an-ecohash-gpu-template-35db</link>
      <guid>https://dev.to/ecohash/run-deepseek-v4-flash-vision-with-an-ecohash-gpu-template-35db</guid>
      <description>&lt;p&gt;n EcoHash platform template saves the configuration you would otherwise assemble yourself: the container image, GPU count, startup command and service port. The DeepSeek GPU template also mounts publisher-provided model weights from shared storage, so you do not need to download another copy before starting the server.&lt;/p&gt;

&lt;p&gt;This walkthrough uses &lt;a href="https://console.ecohash.com/templates/51" rel="noopener noreferrer"&gt;deepseek-v4-flash-8gpu-instance&lt;/a&gt;. Check that its resource kind reads &lt;strong&gt;GPU Instance&lt;/strong&gt;. A similarly named Model Instance template creates a different resource, with different access and lifecycle routes.&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%2Fer0f7sw9yhn14qkc4hqv.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%2Fer0f7sw9yhn14qkc4hqv.png" alt=" " width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The template detail page shows the configuration and a quote for your account. Prices and available capacity can change.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start in the console
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Compute → Templates → Platform&lt;/strong&gt;, then select the DeepSeek GPU template.&lt;/li&gt;
&lt;li&gt;Review its resources and README. The published configuration uses eight RTX PRO 6000 GPUs, SGLang and service port 8000. Keep the preset image and startup command for your first launch.&lt;/li&gt;
&lt;li&gt;Review the region, capacity and pricing breakdown. Shared model weights can determine the region; the current DeepSeek launch form selects Atlanta and locks that field. A quote does not reserve capacity.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Launch&lt;/strong&gt; to open the prefilled GPU-instance form. Add your SSH public key if you want shell access, and review the duration and storage settings.&lt;/li&gt;
&lt;li&gt;Confirm the launch only after checking the credit hold. Open the new instance's detail page to follow its status and find its access 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhpd5vn6mbdupy8vqs4l9.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%2Fhpd5vn6mbdupy8vqs4l9.png" alt=" " width="672" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The template opens the GPU launch form. Reviewing this form does not start an instance; its final Launch button does.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The container can be running while the inference engine is still loading. Wait for the model server to answer before sending a generation request. The template README provides a startup estimate; it is not a guaranteed readiness time.&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%2Fmcnca47yfj71qm5zb6qj.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%2Fmcnca47yfj71qm5zb6qj.png" alt=" " width="672" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep the template's shared model weights and HTTP port. Add persistent storage separately for results you need to retain.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the API
&lt;/h2&gt;

&lt;p&gt;You need &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;jq&lt;/code&gt; and an EcoHash API key. Read-only Compute access permits template discovery and quoting; launching and terminating GPU instances requires &lt;strong&gt;Full&lt;/strong&gt; Compute access. Keep the key in an environment variable. See &lt;a href="https://docs.ecohash.com/getting-started/api-keys" rel="noopener noreferrer"&gt;API-key permissions&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read the template and review its quote
&lt;/h3&gt;

&lt;p&gt;Set &lt;code&gt;ECOHASH_API_KEY&lt;/code&gt; in your shell before running these commands. They read the template and request a quote; they do not launch an instance.&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;set&lt;/span&gt; &lt;span class="nt"&gt;-euo&lt;/span&gt; pipefail
&lt;span class="nv"&gt;API&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://api.ecohash.com"&lt;/span&gt;
&lt;span class="nv"&gt;TEMPLATE_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;51
: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ECOHASH_API_KEY&lt;/span&gt;:?Set&lt;span class="p"&gt; ECOHASH_API_KEY first&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$API&lt;/span&gt;&lt;span class="s2"&gt;/compute-templates/&lt;/span&gt;&lt;span class="nv"&gt;$TEMPLATE_ID&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="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; template.json
jq &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'.template.target_kind == "gpu_instance"'&lt;/span&gt; template.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null

curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$API&lt;/span&gt;&lt;span class="s2"&gt;/compute-templates/quote"&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 &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_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="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;template_id&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;$TEMPLATE_ID&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;hours&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;:1}"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; quote.json
jq &lt;span class="s1"&gt;'{lines,upfront_hold_usd,recurring_daily_usd,capacity_ok,warnings}'&lt;/span&gt; quote.json
jq &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'.capacity_ok == true and (.region_id|length&amp;gt;0) and (.gpu_type|length&amp;gt;0)'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  quote.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;target_kind&lt;/code&gt; check prevents a Model Instance template from being sent to the GPU-instance endpoint. If the quote reports unavailable capacity or a warning you cannot resolve, stop before creating the instance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prepare the launch request
&lt;/h3&gt;

&lt;p&gt;Copy the template's &lt;code&gt;spec&lt;/code&gt;, then add its ID and the quoted region and GPU type. This example sets a one-hour duration and includes your SSH public key. Replace the public-key file path if yours differs. Never use your private-key file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;jq &lt;span class="nt"&gt;--slurpfile&lt;/span&gt; q quote.json &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--rawfile&lt;/span&gt; ssh &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh/id_ed25519.pub"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'.spec + {
    template_id: .template.id,
    name: "deepseek-template-demo",
    region_id: $q[0].region_id,
    gpu_type: $q[0].gpu_type,
    estimated_duration_hours: 1,
    ssh_enabled: true,
    ssh_public_key: ($ssh|rtrimstr("\n"))
  }'&lt;/span&gt; template.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; launch.json
&lt;span class="nb"&gt;cat &lt;/span&gt;launch.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The next POST creates billable compute.&lt;/strong&gt; Review &lt;code&gt;launch.json&lt;/code&gt;, the quote and any warnings first. Sending only &lt;code&gt;template_id&lt;/code&gt; is insufficient; the request must include the template's launch configuration.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$API&lt;/span&gt;&lt;span class="s2"&gt;/gpu-instances"&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 &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_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="s2"&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; @launch.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the returned instance ID. Use it to check status and retrieve the connection details:&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;INSTANCE_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;id returned by the launch request&amp;gt;"&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$API&lt;/span&gt;&lt;span class="s2"&gt;/gpu-instances/&lt;/span&gt;&lt;span class="nv"&gt;$INSTANCE_ID&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="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Send a request to the model server
&lt;/h2&gt;

&lt;p&gt;Once the server is ready, list its models and use the returned model ID. The public service URL forwards requests to the container's HTTP server on port 8000 and requires authentication.&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;SERVICE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$API&lt;/span&gt;&lt;span class="s2"&gt;/gpu-instances/&lt;/span&gt;&lt;span class="nv"&gt;$INSTANCE_ID&lt;/span&gt;&lt;span class="s2"&gt;/service/v1"&lt;/span&gt;
&lt;span class="nv"&gt;MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SERVICE&lt;/span&gt;&lt;span class="s2"&gt;/models"&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 &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-er&lt;/span&gt; &lt;span class="s1"&gt;'.data[0].id'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

curl &lt;span class="nt"&gt;-fsS&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SERVICE&lt;/span&gt;&lt;span class="s2"&gt;/chat/completions"&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 &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_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="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;--arg&lt;/span&gt; model &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$MODEL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'{
    model: $model,
    messages: [{role:"user",content:"Explain tensor parallelism in two sentences."}],
    max_tokens: 1024
  }'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful chat request returns an OpenAI-compatible response. If the model-list request fails while the engine is initializing, check the instance status and startup logs rather than sending repeated generation requests. For your own server configuration, the application must listen on &lt;code&gt;0.0.0.0&lt;/code&gt; at the exposed port.&lt;/p&gt;

&lt;p&gt;For a &lt;strong&gt;Model Instance&lt;/strong&gt;, the documented calling convention instead uses &lt;code&gt;https://api.ecohash.com/v1/chat/completions&lt;/code&gt; with &lt;code&gt;model="&amp;lt;name&amp;gt;:&amp;lt;instance_id&amp;gt;"&lt;/code&gt;. Do not use that routing convention for this GPU-instance walkthrough. See &lt;a href="https://docs.ecohash.com/user-inference/calling-endpoint" rel="noopener noreferrer"&gt;calling a model endpoint&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finish the evaluation
&lt;/h2&gt;

&lt;p&gt;Save your results to persistent storage before terminating the GPU instance. Its local &lt;code&gt;/workspace&lt;/code&gt; scratch data is temporary.&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;-fsS&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$API&lt;/span&gt;&lt;span class="s2"&gt;/gpu-instances/&lt;/span&gt;&lt;span class="nv"&gt;$INSTANCE_ID&lt;/span&gt;&lt;span class="s2"&gt;/terminate"&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 &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This termination route is for GPU instances. Manage a Model Instance through its own lifecycle controls; terminating one resource type is not a substitute for stopping the other.&lt;/p&gt;

&lt;p&gt;A reservation-backed quote may show no additional hourly compute charge because capacity is covered by a reservation agreement. This does not mean the service is free. Review your account's quote and terms; separately retained storage may continue to incur charges.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://console.ecohash.com/templates" rel="noopener noreferrer"&gt;Open platform templates&lt;/a&gt; · &lt;a href="https://docs.ecohash.com/api-reference/gpu-instances" rel="noopener noreferrer"&gt;GPU-instance API reference&lt;/a&gt;&lt;/p&gt;




</description>
      <category>ai</category>
      <category>cloudcomputing</category>
      <category>infrastructure</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>How to launch an 8-GPU RTX PRO 6000 instance on EcoHash</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Thu, 22 Oct 2026 03:48:35 +0000</pubDate>
      <link>https://dev.to/ecohash/how-to-launch-an-8-gpu-rtx-pro-6000-instance-on-ecohash-32fj</link>
      <guid>https://dev.to/ecohash/how-to-launch-an-8-gpu-rtx-pro-6000-instance-on-ecohash-32fj</guid>
      <description>&lt;p&gt;An eight-GPU instance in EcoHash's Atlanta region gives you a whole node: eight RTX PRO 6000 GPUs with 96 GB of VRAM each, 200 vCPUs, 1,352 GB of RAM, and up to 5,260 GiB of temporary local scratch space. You can start with an EcoHash container image or bring the stack you already use.&lt;/p&gt;

&lt;p&gt;This walkthrough covers the choices that matter before you launch, how to connect afterward, and where to put files you need to keep. Open &lt;a href="https://console.ecohash.com/gpu-instances" rel="noopener noreferrer"&gt;GPU Instances in the console&lt;/a&gt; to follow along. You will need an account with enough credit for the configuration you select.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose Atlanta and all eight GPUs
&lt;/h2&gt;

&lt;p&gt;Click &lt;strong&gt;Launch Instance&lt;/strong&gt;, give the instance a name, and select &lt;strong&gt;atl&lt;/strong&gt; for Atlanta. Under &lt;strong&gt;GPUs per Instance&lt;/strong&gt;, choose &lt;strong&gt;8x&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The configuration summary now shows the whole node dedicated to this instance. The eight GPUs provide 768 GB of total VRAM, with 96 GB on each GPU. That is memory distributed across eight devices; your serving or training software must support using multiple GPUs to take advantage of 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbwr0vwq50xkcolop0a50.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%2Fbwr0vwq50xkcolop0a50.png" alt="EcoHash launch form with Atlanta selected and eight RTX PRO 6000 GPUs, 200 vCPUs, 1,352 GB RAM and temporary scratch storage." width="799" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecting eight GPUs allocates the whole node. Check the resource summary for your chosen region.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pick a container for the work you want to run
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;EcoHash Images&lt;/strong&gt; tab offers several starting points. Their names include the installed software versions, so check the dropdown rather than relying on a tag from an old tutorial.&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%2Fzq2n24x8b18ugexsunes.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%2Fzq2n24x8b18ugexsunes.png" alt="EcoHash Images dropdown listing GPU Base, GPU Jupyter, GPU Inference, and CUDA Bare images with their software versions." width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the inference image for vLLM, Jupyter for notebooks, or a base image for your own stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPU Inference:&lt;/strong&gt; vLLM configured for the RTX PRO 6000. This is the starting point for serving an LLM. It is a large image, so the first launch on a node may spend several minutes downloading it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU Base:&lt;/strong&gt; a CUDA and PyTorch environment for installing your own software. Choose the CUDA version your workload needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CUDA Bare:&lt;/strong&gt; a CUDA 13.0 image without a framework, for building your environment from a smaller starting point.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU Jupyter:&lt;/strong&gt; JupyterLab and an ML environment for browser-based notebook work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The optional &lt;strong&gt;Startup Command&lt;/strong&gt; runs when the instance starts. Use it to launch your application or model server. If you leave it blank, the image's default command applies. Make sure that command keeps the container running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bringing your own image
&lt;/h3&gt;

&lt;p&gt;Open &lt;a href="https://console.ecohash.com/images" rel="noopener noreferrer"&gt;Images&lt;/a&gt; under Registry and click &lt;strong&gt;Add Image&lt;/strong&gt;. Enter a display name and the full image reference, including its tag. For example, &lt;code&gt;registry.example.com/team/eval:v1.0&lt;/code&gt; is the format; replace it with your real registry and image.&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%2Fums7f210nr043z7515zm.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%2Fums7f210nr043z7515zm.png" alt="Add Container Image form with an example display name and registry reference, and empty optional private registry credential fields." width="800" height="827"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A public image needs only its reference. Private images also need credentials with pull access.&lt;/p&gt;

&lt;p&gt;For a private registry, provide its username and a read/pull access token. The form displays guidance for the registry you enter. AWS ECR login tokens expire after 12 hours and cannot be saved for this workflow; use a public ECR repository or arrange for EcoHash's account to have pull access.&lt;/p&gt;

&lt;p&gt;Before saving the image, check these requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture:&lt;/strong&gt; build for &lt;code&gt;linux/amd64&lt;/code&gt;. On an Apple Silicon Mac, include &lt;code&gt;--platform linux/amd64&lt;/code&gt; in your &lt;code&gt;docker buildx build&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CUDA:&lt;/strong&gt; use CUDA 13.0 or earlier for the configuration described here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU support:&lt;/strong&gt; your framework and CUDA extensions must support Blackwell &lt;code&gt;sm_120&lt;/code&gt;. Check the specific build you are using, especially if you compile extensions yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH:&lt;/strong&gt; EcoHash configures SSH automatically for Debian, Ubuntu, and Alpine-based images. Include OpenSSH yourself for other base distributions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Save the image, return to the launch form, and select it under &lt;strong&gt;Custom / Registry&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up SSH and an HTTP endpoint
&lt;/h2&gt;

&lt;p&gt;Enable &lt;strong&gt;SSH access&lt;/strong&gt; and add your public SSH key in the launch form. Keys are applied when the instance starts, so do this before launching. Keep the matching private key on your own computer.&lt;/p&gt;

&lt;p&gt;If you want to call a model server or another HTTP application, enable &lt;strong&gt;Expose a public service URL&lt;/strong&gt; and enter the port your application listens on inside the container, such as &lt;strong&gt;8000&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%2Fng8txhgexue7foqbef2v.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%2Fng8txhgexue7foqbef2v.png" alt="Public service URL option enabled in the EcoHash launch form with container port 8000 and session or API key authentication guidance." width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The endpoint forwards to the HTTP port inside your container.&lt;/p&gt;

&lt;p&gt;Your application must listen on &lt;code&gt;0.0.0.0&lt;/code&gt;, not only on &lt;code&gt;127.0.0.1&lt;/code&gt;. A process bound to localhost can run normally inside the container while remaining unreachable through the public URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the runtime and attach storage
&lt;/h2&gt;

&lt;p&gt;Select &lt;strong&gt;No end time&lt;/strong&gt; if you want the instance to run until you terminate it. The form explains the credit hold and hourly deductions. This setting does not keep an instance running after the account runs out of credit.&lt;/p&gt;

&lt;p&gt;Alternatively, choose a fixed estimated duration if you want an automatic end time. Read the billing summary before launching; it changes with the number of GPUs and the duration you select.&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%2Fgufrccadb01vuw4qhqm2.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%2Fgufrccadb01vuw4qhqm2.png" alt="No end time selected with hourly billing guidance and controls for attaching cloud drives and shared filesystems." width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Attach persistent storage before starting work you need to keep.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;cloud drive&lt;/strong&gt; attaches to one instance at a time. A &lt;strong&gt;shared filesystem&lt;/strong&gt; can be attached to several instances. Both are retained after the compute instance ends. Choose a cloud drive for files used by this instance, or a shared filesystem when several instances need the same datasets, weights, or results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Treat&lt;/strong&gt; &lt;code&gt;/workspace&lt;/code&gt; &lt;strong&gt;as temporary.&lt;/strong&gt; Its local scratch data is erased when the instance ends, including when it stops because your account balance runs out. Write results you need to keep to an attached cloud drive or shared filesystem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Review the GPU count, image, SSH keys, service port, duration, and storage attachments. Then click &lt;strong&gt;Launch&lt;/strong&gt;. Allow extra time for the first download of a large container image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connect and check your application
&lt;/h2&gt;

&lt;p&gt;Once the instance is running, its detail page shows the SSH command, the public URL if you enabled one, and a web terminal you can open in the browser. Copy the SSH command from that page rather than constructing the hostname or port yourself.&lt;/p&gt;

&lt;p&gt;In the terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this configuration, the output should list eight RTX PRO 6000 GPUs. Check that your application can see all eight before starting a long job.&lt;/p&gt;

&lt;p&gt;The public URL requires your console login or an EcoHash API key. To call it from a script, send the key in an &lt;code&gt;Authorization: Bearer&lt;/code&gt; header. Paths after &lt;code&gt;/service&lt;/code&gt; pass through to your application: &lt;code&gt;/service/v1/models&lt;/code&gt; reaches the container as &lt;code&gt;/v1/models&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a vLLM server exposing that route, copy the instance's public URL and test it with:&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;export &lt;/span&gt;&lt;span class="nv"&gt;ECOHASH_SERVICE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://api.ecohash.com/gpu-instances/INSTANCE_ID/service"&lt;/span&gt;
&lt;span class="c"&gt;# Set ECOHASH_API_KEY in your environment before running this request.&lt;/span&gt;
curl &lt;span class="nt"&gt;--fail-with-body&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ECOHASH_SERVICE_URL&lt;/span&gt;&lt;span class="p"&gt;%/&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/v1/models"&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 &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ECOHASH_API_KEY&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;INSTANCE_ID&lt;/code&gt; with your instance ID, or use the full URL copied from the console. A ready vLLM server should return a model list. For another application, use one of its own HTTP routes instead.&lt;/p&gt;

&lt;p&gt;If the request fails, check that the application has finished starting, listens on &lt;code&gt;0.0.0.0&lt;/code&gt;, and uses the same port you entered in the console. Also confirm that your request includes a valid API key.&lt;/p&gt;

&lt;p&gt;Before ending the session, confirm that your outputs are on persistent storage. Terminate the instance when you are finished to stop compute charges.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://console.ecohash.com/gpu-instances" rel="noopener noreferrer"&gt;Open GPU Instances&lt;/a&gt; to configure a node, or read more about &lt;a href="https://docs.ecohash.com/gpu-compute/launching-instance" rel="noopener noreferrer"&gt;launching an instance&lt;/a&gt; and &lt;a href="https://docs.ecohash.com/gpu-compute/container-images" rel="noopener noreferrer"&gt;container images&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>cloud</category>
      <category>infrastructure</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Qwen-Image-2.1 on RTX PRO 6000: 15-Image Quality and Performance Test</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Fri, 16 Oct 2026 03:53:35 +0000</pubDate>
      <link>https://dev.to/ecohash/qwen-image-21-on-rtx-pro-6000-15-image-quality-and-performance-test-567n</link>
      <guid>https://dev.to/ecohash/qwen-image-21-on-rtx-pro-6000-15-image-quality-and-performance-test-567n</guid>
      <description>&lt;p&gt;Qwen-Image-2.1 combines text-to-image generation, image editing, multilingual typography, native 2K output, and RGBA transparency in one model. We wanted to answer a practical question for researchers considering a 96 GB workstation-class GPU: &lt;strong&gt;what quality and speed can one NVIDIA RTX PRO 6000 Blackwell Server Edition actually deliver?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On September 24, 2026, we ran 15 fixed-seed prompts through the official Diffusers pipeline. The set covered English and bilingual typography, portrait and product photography, architecture, landscapes, illustration, a transparent asset, and one native 2048 × 2048 render.&lt;/p&gt;

&lt;p&gt;Representative outputs from the full 15-image run are included below. We did not rerun prompts to select more favorable outputs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;License note:&lt;/strong&gt; This article documents an independent, non-commercial technical evaluation. Qwen-Image-2.1 is distributed under the &lt;a href="https://github.com/QwenLM/Qwen-Image-2.1/blob/main/LICENSE" rel="noopener noreferrer"&gt;Qwen Research License Agreement&lt;/a&gt;, which limits the model materials to non-commercial research or evaluation unless a separate commercial license is obtained. This article does not distribute model weights, provide a hosted Qwen-Image-2.1 service, or grant commercial-use rights.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Results at a glance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Approximately 1 megapixel
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;14 samples&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;BF16, 40 steps, batch size 1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;9.378 seconds per image on average&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;36.801 GiB average peak allocated GPU memory&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Native 2048 × 2048
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;1 sample&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;BF16, 40 steps, batch size 1&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;52.021 seconds&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;56.516 GiB peak allocated GPU memory&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;15/15&lt;/strong&gt; requested samples completed without an out-of-memory or CUDA error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The 14 approximately 1 MP samples ranged from &lt;strong&gt;9.271 to 9.524 seconds&lt;/strong&gt;, with a 9.375-second median.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Warm-cache pipeline loading took &lt;strong&gt;4.427 seconds&lt;/strong&gt;. Initial model download time was excluded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Total recorded generation time for all 15 images was &lt;strong&gt;183.317 seconds&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At the measured sequential rate, 1 MP generation corresponds to roughly &lt;strong&gt;384 images per GPU-hour&lt;/strong&gt; before orchestration, file I/O, safety review, retries, or model-loading overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The transparent sample contains a real alpha channel, rather than a simulated solid-color background.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These figures describe one configuration, not a universal model benchmark. We did not test batching, reduced-step schedules, quantization, CPU offload, or alternative inference runtimes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test environment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPU:&lt;/strong&gt; NVIDIA RTX PRO 6000 Blackwell Server Edition&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU memory reported by PyTorch:&lt;/strong&gt; 95.0 GiB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute capability:&lt;/strong&gt; 12.0&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NVIDIA driver:&lt;/strong&gt; 580.105.08&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyTorch:&lt;/strong&gt; 2.11.0+cu128&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyTorch CUDA runtime:&lt;/strong&gt; 12.8&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline:&lt;/strong&gt; Diffusers &lt;code&gt;QwenImage21Pipeline&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Precision:&lt;/strong&gt; BF16, without quantization or CPU offload&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference steps:&lt;/strong&gt; 40&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch size:&lt;/strong&gt; 1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test date:&lt;/strong&gt; September 24, 2026&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All images used deterministic recorded seeds. Peak-memory figures are PyTorch peak allocated memory for each generation, not total board power, reserved memory, or whole-system memory consumption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typography: the strongest part of this run
&lt;/h2&gt;

&lt;p&gt;Four prompts explicitly required rendered text. In this single fixed-seed run, all four produced the requested words correctly. That is an encouraging result, but it is &lt;strong&gt;four observed samples, not a 100% text-accuracy claim&lt;/strong&gt;. Three representative typography results are shown below.&lt;/p&gt;

&lt;h3&gt;
  
  
  English neon sign
&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%2Fawl2ylk6io01pat9kpmr.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%2Fawl2ylk6io01pat9kpmr.png" alt="A generated rainy-night studio with a neon sign reading MAKE IDEAS VISIBLE" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“MAKE IDEAS VISIBLE” is correctly spelled and follows the perspective of the storefront rather than appearing as a flat overlay. Reflections, mist, glass, and mixed cyan-and-amber light make the result feel spatially integrated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Educational infographic
&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%2Fo5kyn7iccf77idiva6ww.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%2Fo5kyn7iccf77idiva6ww.jpg" alt="A generated infographic titled HOW RAIN BECOMES A RIVER" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The title and all four labels—“CLOUD,” “RAIN,” “SOIL,” and “RIVER”—are correct. The visual logic is less reliable: the cloud panel already shows rain, so the first two stages are not as distinct as the labels imply. This is a useful reminder that correct typography does not guarantee correct instructional content.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bilingual storefront
&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%2F614djzzvwq4gq6678ath.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%2F614djzzvwq4gq6678ath.jpg" alt="A generated bookstore storefront with bilingual signage" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was the most demanding text sample: two languages, two lines, a fascia sign, interior shelves, reflective glass, and softly blurred pedestrians. Both requested lines rendered correctly in the requested order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Photographic output
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Editorial portrait
&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%2Fxs49aa22edahxqvl28uk.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%2Fxs49aa22edahxqvl28uk.jpg" alt="A generated editorial portrait of a fictional ceramic artist" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fictional subject has natural-looking skin texture, warm window light, believable fabric, and visible clay dust. Hands and fingers remained plausible in this sample, though anatomy should always be reviewed at full resolution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Product photography
&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%2F12pumb7zqifh9iifblhz.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%2F12pumb7zqifh9iifblhz.jpg" alt="A generated studio product photograph of an unbranded black speaker" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The model separated matte polymer, woven grille, and copper-like metal convincingly. The floating composition and controlled shadow are useful for concept work. Exact product representation would still require reference conditioning and human verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Food editorial
&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%2F41ku7r9wid9quhmwtlve.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%2F41ku7r9wid9quhmwtlve.jpg" alt="A generated editorial food photograph of noodles with chili oil" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The noodles, chili oil, sesame, scallions, ceramic bowl, and a subtle trace of steam are clearly differentiated. The prompt requested a top-down view, but the output is closer to a 45-degree overhead angle—an example of attractive output that does not fully obey the camera instruction.&lt;/p&gt;

&lt;h3&gt;
  
  
  E-commerce layout
&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%2F3t2tlv7hc338x15ztmru.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%2F3t2tlv7hc338x15ztmru.jpg" alt="A generated product hero image with a bottle on the right and copy space on the left" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reusable bottle appears on the right with generous negative space on the left, matching the requested layout. Small condensation droplets and the soft shadow are handled cleanly without introducing a brand or logo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture and landscape
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reading room built around a tree
&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%2Fsh3d2b9kgtxz2csew90u.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%2Fsh3d2b9kgtxz2csew90u.jpg" alt="A generated curved timber reading room built around an old tree" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Curved timber walls, glazing, bookshelves, sunlight, and the central tree read as a coherent space. As with most generated architecture, junctions and construction details deserve close inspection before the image is used as more than a concept.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alpine landscape after a storm
&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%2Fa05ajeorefwfwbkxpezw.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%2Fa05ajeorefwfwbkxpezw.jpg" alt="A generated panoramic alpine landscape after a summer storm" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The narrow river catches the requested shaft of light, atmospheric depth remains readable across several ridgelines, and tiny hikers provide scale without dominating the scene.&lt;/p&gt;

&lt;h2&gt;
  
  
  Illustration and reusable assets
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Storybook illustration
&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%2Fbnnt0srfh1nmemwm278j.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%2Fbnnt0srfh1nmemwm278j.jpg" alt="A generated storybook illustration of a tiny robot gardener" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result preserves the prompt’s gouache-and-colored-pencil character across the robot, luminous flowers, warm windows, and dusk sky. The character is fictional and was explicitly requested as a non-franchise design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transparent RGBA sticker
&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%2F1fa5nerubkvvaip24leg.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%2F1fa5nerubkvvaip24leg.png" alt="A generated blue origami whale sticker with a transparent background" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This PNG has a valid alpha channel with values from 0 to 255. Of 1,048,576 pixels, &lt;strong&gt;989,473 are not fully opaque&lt;/strong&gt;. That verifies actual transparency rather than a white or checkerboard background painted into the image. Some viewers may display transparent RGB values against a colored matte; that does not change the alpha data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vertical editorial composition
&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%2Ft2d3v0e2zwi016qd2uz8.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%2Ft2d3v0e2zwi016qd2uz8.jpg" alt="A generated vertical coastal railway scene at sunrise" width="768" height="1344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 9:16 result reserves open sky for copy while keeping the fictional cliffside railway, turquoise water, and sunrise readable at social-media proportions.&lt;/p&gt;

&lt;h3&gt;
  
  
  3D application icon
&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%2Fibdhwj3ry2hlhx6a9g9o.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%2Fibdhwj3ry2hlhx6a9g9o.jpg" alt="A generated 3D focus timer icon with an hourglass symbol" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The centered orthographic view, glass-like blue tile, ivory hourglass, and cyan inner glow form a clean fictional icon without text or third-party marks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Native 2K output
&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%2F9kk0nr7ry9ecfxjsnsy2.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%2F9kk0nr7ry9ecfxjsnsy2.jpg" alt="A native 2048 by 2048 generated image of an imaginary coastal observatory" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final prompt generated a 2048 × 2048 image directly, without a separate upscaler. It deliberately asked for a detail-heavy fictional observatory with dozens of small windows, railings, weathered copper, concrete, waves, rocks, and a distant horizon.&lt;/p&gt;

&lt;p&gt;At normal viewing size, the result is coherent and richly textured. At 100% zoom, water staining, window frames, and material transitions remain useful, although a few railing paths and small structural junctions are not physically convincing.&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%2Facx2tc738zp4b09s4vvc.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%2Facx2tc738zp4b09s4vvc.jpg" alt="A 100 percent crop from the native 2K observatory output" width="700" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 2K render required &lt;strong&gt;52.021 seconds&lt;/strong&gt; and &lt;strong&gt;56.516 GiB&lt;/strong&gt; of peak allocated GPU memory. Compared with the approximately 1 MP group, it used about 1.54× the memory and 5.55× the time for roughly four times the pixels. Native high-resolution diffusion is therefore practical on this 96 GB card, but it is substantially more expensive than first generating at approximately 1 MP.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the RTX PRO 6000 changes
&lt;/h2&gt;

&lt;p&gt;The main advantage in this test was not merely that the model ran. It ran in BF16 without quantization, model sharding, or CPU offload, while retaining substantial memory headroom:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Approximately 1 MP generation peaked near &lt;strong&gt;36.8 GiB&lt;/strong&gt;, leaving roughly &lt;strong&gt;58 GiB&lt;/strong&gt; relative to the 95.0 GiB reported by PyTorch.&lt;/li&gt;
&lt;li&gt;Native 2048 × 2048 generation peaked at &lt;strong&gt;56.5 GiB&lt;/strong&gt;, leaving roughly &lt;strong&gt;38.5 GiB&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Runtime variation across the 14 similarly sized samples was under three percent from fastest to slowest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That headroom may be useful for experimentation with concurrency, larger conditioning inputs, prompt-rewriting components, or alternative runtimes. This test did not measure those scenarios, so it should not be read as a batching or multi-user capacity claim.&lt;/p&gt;

&lt;p&gt;For researchers optimizing total throughput, the result also suggests a practical workflow: generate candidates near 1 MP, review them, and reserve native 2K generation for selected outputs. That conclusion follows from the measured latency difference; it is not a statement about every pipeline or quality target.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the model still needs human review
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text:&lt;/strong&gt; Four text prompts succeeded in this run, but longer copy, smaller type, unusual fonts, and denser layouts need broader testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instruction following:&lt;/strong&gt; The food image missed the requested top-down camera angle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic accuracy:&lt;/strong&gt; The infographic rendered its labels correctly but did not clearly separate the first two stages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fine structure:&lt;/strong&gt; Railings, window grids, hands, and other repeated small geometry should be checked at 100% zoom.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production claims:&lt;/strong&gt; Attractive output is not evidence that a depicted product, building, process, or person is accurate.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In this fixed-seed evaluation, Qwen-Image-2.1 produced a broad range of visually useful outputs on a single RTX PRO 6000. Approximately 1 MP images completed consistently in about 9.4 seconds at 40 steps, while native 2K completed in about 52 seconds. The card’s 96 GB memory class allowed the official BF16 Diffusers path to run without memory-saving compromises in the tested configuration.&lt;/p&gt;

&lt;p&gt;The strongest observed results were multilingual typography, photographic material rendering, composition with deliberate copy space, and real RGBA transparency. The main limitations were familiar but important: semantic mistakes can survive correct typography, camera instructions may be missed, and tiny repeated structures still require human review.&lt;/p&gt;

&lt;p&gt;For anyone evaluating this hardware-model combination, the practical takeaway is straightforward: one RTX PRO 6000 provides ample memory for Qwen-Image-2.1 research at both approximately 1 MP and native 2K, with predictable single-image latency in this configuration.&lt;/p&gt;




&lt;h2&gt;
  
  
  License, rights, and attribution
&lt;/h2&gt;

&lt;p&gt;This evaluation was conducted independently by EcoHash for research and technical assessment. EcoHash is not affiliated with, endorsed by, or sponsored by Qwen, Alibaba, or NVIDIA in connection with this article.&lt;/p&gt;

&lt;p&gt;Qwen-Image-2.1 is distributed under the &lt;a href="https://github.com/QwenLM/Qwen-Image-2.1/blob/main/LICENSE" rel="noopener noreferrer"&gt;Qwen Research License Agreement&lt;/a&gt;. The license permits use of the model materials for non-commercial research or evaluation and requires a separate license for commercial use. Readers must review the current upstream license and obtain any permissions required for their intended use. The official model repository is available on &lt;a href="https://huggingface.co/Qwen/Qwen-Image-2.1" rel="noopener noreferrer"&gt;Hugging Face&lt;/a&gt;, and the official project repository is available on &lt;a href="https://github.com/QwenLM/Qwen-Image-2.1" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The example images in this article were generated from original prompts for this evaluation. They use fictional people, fictional places, unbranded objects, and non-franchise characters. AI-generated output is not automatically cleared of third-party copyright, trademark, publicity, privacy, or other rights; the applicable risk depends on the prompt, reference inputs, output, jurisdiction, and intended use. Users remain responsible for reviewing outputs and securing any necessary rights.&lt;/p&gt;

&lt;p&gt;“Qwen,” “Alibaba,” “NVIDIA,” and “RTX” are names or marks of their respective owners and are used here only for factual identification. Product specifications and software licenses may change; verify current upstream documentation before relying on this evaluation.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>deeplearning</category>
      <category>hardware</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>How to deploy and tune Qwen3.8-27B on one RTX Pro 6000</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Thu, 15 Oct 2026 04:08:40 +0000</pubDate>
      <link>https://dev.to/ecohash/how-to-deploy-and-tune-qwen38-27b-on-one-rtx-pro-6000-2dd5</link>
      <guid>https://dev.to/ecohash/how-to-deploy-and-tune-qwen38-27b-on-one-rtx-pro-6000-2dd5</guid>
      <description>&lt;p&gt;Qwen3.8-27B is 27B dense, published in FP8 under Apache-2.0, and the weights plus runtime overhead come to about 29 GiB. A single RTX Pro 6000 holds it with a large KV cache still to spare, on one process, with no tensor parallelism to configure. This post is the serving config EcoHash runs in production, the settings whose obvious alternative fails, and the one flag that took a single card from 999.9 to 1954.0 output tokens/sec.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Everything needed to run it well is in the download, including the draft head that doubles what one card serves.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why this model suits self-hosting
&lt;/h2&gt;

&lt;p&gt;At FP8 the checkpoint is 28.75 GiB on disk, and vLLM reports 29.34 GiB of weights and non-torch overhead once loaded. On a 96 GB card that leaves 53.8 GiB for KV cache, which is 767,317 tokens. Nothing has to be split across devices and nothing runs close to the edge.&lt;/p&gt;

&lt;p&gt;Apache-2.0 means no usage terms to read. Context is 262,144 tokens natively, extensible to 1M. The &lt;a href="https://huggingface.co/Qwen/Qwen3.8-27B" rel="noopener noreferrer"&gt;official model card&lt;/a&gt; reports 89.2 on GPQA Diamond, 90.3 on LiveCodeBench v6, 61.7 on SWE-bench Pro, and 73.0 on Terminal Bench 2.1. &lt;a href="https://artificialanalysis.ai/models/qwen3-8-27b" rel="noopener noreferrer"&gt;Artificial Analysis&lt;/a&gt; puts it at 52 on their Intelligence Index, level with GPT-5.6 Luna and one point behind GLM-5.2 (753B) and DeepSeek V4 Pro (1.7T). Downloads passed &lt;a href="https://cybernews.com/tech/qwen-38-27b-ai-model-debuts-with-million-downloads/" rel="noopener noreferrer"&gt;three million&lt;/a&gt; within days of the 14 August 2026 release.&lt;/p&gt;

&lt;p&gt;The checkpoint also carries its own multi-token-prediction draft head, 22 tensors and 0.44 GiB, in the same download. Speculative decoding normally means training or sourcing a second model; here it is a flag.&lt;/p&gt;

&lt;p&gt;Plan for one quirk. Artificial Analysis needed 160 million output tokens to run this model through their index, against a 43 million median for comparable open-weight models, and Simon Willison found the same thing: it is &lt;a href="https://simonwillison.net/2026/Aug/16/qwen-38-27b/" rel="noopener noreferrer"&gt;excellent, but it defaults to wildly overthinking things&lt;/a&gt;. Because it reasons at length by default, decode throughput rather than prefill is what repays tuning.&lt;/p&gt;

&lt;h2&gt;
  
  
  The serving config
&lt;/h2&gt;

&lt;p&gt;This is what runs in production, on vLLM 0.27.1 with driver 580.105.08 and CUDA 13.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vllm serve /path/to/Qwen3.8-27B-FP8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--served-model-name&lt;/span&gt; qwen3.8-27b &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dtype&lt;/span&gt; bfloat16 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tensor-parallel-size&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-model-len&lt;/span&gt; 32768 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--gpu-memory-utilization&lt;/span&gt; 0.90 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--max-num-seqs&lt;/span&gt; 128 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prefix-caching&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-prompt-tokens-details&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--reasoning-parser&lt;/span&gt; qwen3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-auto-tool-choice&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tool-call-parser&lt;/span&gt; qwen3_xml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--safetensors-load-strategy&lt;/span&gt; prefetch &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--speculative-config&lt;/span&gt; &lt;span class="s1"&gt;'{"method":"mtp","num_speculative_tokens":3}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Five of those lines are there because the obvious alternative failed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--dtype bfloat16&lt;/code&gt;, not float16. FP8 checkpoints dispatch to kernels that assert a bf16 output dtype. With float16 the engine loads every weight, reports success, then crash-loops at warmup. It cost a failed rollout on a sibling model before anyone connected the two.&lt;/li&gt;
&lt;li&gt;No &lt;code&gt;--quantization&lt;/code&gt; flag. The checkpoint is already FP8 (e4m3, weight block size 128x128), so vLLM reads &lt;code&gt;quantization_config&lt;/code&gt; from &lt;code&gt;config.json&lt;/code&gt; and loads straight through. Passing the flag anyway makes it quantize at runtime on &lt;em&gt;every&lt;/em&gt; start: 2105 seconds of weight loading against 17 seconds pre-quantized.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--safetensors-load-strategy prefetch&lt;/code&gt; if the weights sit on network storage. vLLM does not always recognise a network filesystem, and sequential loading falls off a cliff past the eighth shard, from 94 seconds to 370 seconds per shard. This checkpoint is sharded per layer, so there are 66 of them.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--tool-call-parser qwen3_xml&lt;/code&gt;, not hermes. Qwen3 emits its native XML tool format rather than Hermes JSON. With the wrong parser you get the raw &lt;code&gt;&amp;lt;tool_call&amp;gt;&lt;/code&gt; text and &lt;code&gt;tool_calls: null&lt;/code&gt;, and every agent integration breaks quietly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--max-num-seqs 128&lt;/code&gt;. This is a dense 27B, so every token touches every weight and the batching knee arrives earlier than it does on an A3B MoE, where 160 is the better setting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;--max-model-len 32768&lt;/code&gt; is a deliberate cap rather than a limit of the model. It keeps the KV cache bounded when the card is shared. Raise it after checking the memory numbers, not before.&lt;/p&gt;

&lt;h2&gt;
  
  
  The flag worth tuning for
&lt;/h2&gt;

&lt;p&gt;The draft head proposes several tokens, the model verifies them in one pass, and the accepted ones come out together. &lt;code&gt;num_speculative_tokens&lt;/code&gt;, K below, is how many it proposes. Deeper drafts win more per step and get rejected more often, so K has an optimum that moves with the workload.&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%2Fefwahtdfkjhpjst49sjn.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%2Fefwahtdfkjhpjst49sjn.png" alt=" " width="560" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;K=3 wins on all three workloads, so that is the setting. Returns are already flattening on chat, where K=2 to K=3 buys 6%, and the acceptance rate is what separates the workloads: predictable, low-entropy output drafts well, open-ended prose does not.&lt;/p&gt;

&lt;p&gt;The effect holds as the card fills up. The dotted line is the 30 ms per-token budget that defines a usable interactive response.&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%2Fgwefne71s6qge2ifbs10.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%2Fgwefne71s6qge2ifbs10.png" alt=" " width="560" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Per-token latency drops from 22 ms to 13 ms on a single stream, and the number of concurrent requests one card holds inside that budget goes from 32 to 64. Aggregate output at the ceiling goes from 999.9 to 1954.0 tokens/sec. Measured in August 2026 on one card at 150-token replies; longer generations shift the numbers, and the full sweep is in the write-up.&lt;/p&gt;

&lt;p&gt;The cost is cache. The draft head brings an attention layer that needs KV of its own, so capacity falls from 767,317 tokens to 592,164, a 23% cut. At 48 to 64 concurrent short requests that is not the binding constraint, but it would become one before pushing concurrency much higher.&lt;/p&gt;

&lt;p&gt;The full write-up has the draft-depth sweep, acceptance rates by position, the whole concurrency table, the memory accounting, and the quality checks: &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks/blob/main/llm/speculative-decoding-qwen3.8-27b.md" rel="noopener noreferrer"&gt;Qwen3.8-27B with MTP speculative decoding&lt;/a&gt;. The raw CSVs are in the same repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the API instead
&lt;/h2&gt;

&lt;p&gt;All of the above is already running. Calling &lt;code&gt;qwen3.8-27b&lt;/code&gt; on EcoHash gets the tuned deployment with nothing to provision: 179 ms to first token, about 78 tokens/sec on a single stream, $0.30 per 1M input tokens and $0.60 per 1M output.&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%2F2mq4wdf33jjmb0ucatzz.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%2F2mq4wdf33jjmb0ucatzz.png" alt=" " width="560" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Peer numbers are as published by &lt;a href="https://openrouter.ai/qwen/qwen3.8-27b" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt; in August 2026. Time to a finished answer is the first token plus the rest of the stream, so a 500-token answer is roughly one step of an agent loop, and the whole field except one provider needs at least 1.7 times as long as EcoHash to produce 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyx723ivldejzgqwa8umk.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%2Fyx723ivldejzgqwa8umk.png" alt=" " width="560" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Blended at three parts input to one part output, that is $0.375 per 1M tokens against $1.05 to $1.21 elsewhere. Almost all of the gap is the output side, $0.60 against $3.00 to $3.40, and output is the side a reasoning model spends on. An agent making 400 requests an hour at 800 input and 2,000 output tokens each costs $0.58 an hour here and $2.70 at $0.45 / $3.20.&lt;/p&gt;

&lt;p&gt;The API is OpenAI-compatible, so only the base URL and the model name change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.ecohash.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eco_...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# create a key at console.ecohash.com
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qwen3.8-27b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Refactor this function and explain the change.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tool calling and structured outputs work, and images go in the same messages array. The shared API serves a 32k context rather than the checkpoint's 262k, which is what keeps the KV cache bounded on a shared card.&lt;/p&gt;

&lt;h2&gt;
  
  
  Or run it yourself on the same card
&lt;/h2&gt;

&lt;p&gt;If the config above is what you want but the hardware is not, an RTX Pro 6000 workspace rents by the second at $1.89 per GPU-hour as of August 2026, with root access and a browser terminal. Pull the FP8 checkpoint, paste the &lt;code&gt;vllm serve&lt;/code&gt; line, and the same deployment is yours to change: the full 262k context, your own &lt;code&gt;--max-num-seqs&lt;/code&gt;, no shared-tenancy cap.&lt;/p&gt;

&lt;p&gt;Which is the argument for self-hosting this particular model. One card covers it, and the tuning that moves the numbers is a flag you can read in a config file.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is this the full model or a quantized version?&lt;/strong&gt; FP8, which is how the Qwen team publishes it. The precision is stated because not every provider states theirs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to do anything to get the speculative decoding speedup on the API?&lt;/strong&gt; No. It is on for every request to &lt;code&gt;qwen3.8-27b&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will it fit on a 48 GB card?&lt;/strong&gt; The weights alone are about 29 GiB, so it loads, but the KV cache left over is small enough that concurrency and context both suffer. The 96 GB card is what makes the deployment comfortable rather than merely possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does MTP change the output?&lt;/strong&gt; Verification means the accepted tokens are the ones the model would have produced anyway. Answers matched on every checkable question in our quality pass; the write-up explains why a byte-for-byte comparison is not the right test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it accept images?&lt;/strong&gt; Yes. It is a vision-language model and takes images in the standard OpenAI content format.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Call the model: &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;/models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rent the card and run the config above: &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;/gpu-compute&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Read the benchmark: &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks/blob/main/llm/speculative-decoding-qwen3.8-27b.md" rel="noopener noreferrer"&gt;Qwen3.8-27B with MTP speculative decoding&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reserve steady capacity: &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;/dedicated-inference&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>ai</category>
      <category>hardware</category>
      <category>llm</category>
      <category>performance</category>
    </item>
    <item>
      <title>Run your Retell AI agent on an open model: the custom LLM bridge</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Wed, 14 Oct 2026 10:44:40 +0000</pubDate>
      <link>https://dev.to/ecohash/run-your-retell-ai-agent-on-an-open-model-the-custom-llm-bridge-5817</link>
      <guid>https://dev.to/ecohash/run-your-retell-ai-agent-on-an-open-model-the-custom-llm-bridge-5817</guid>
      <description>&lt;p&gt;Retell AI prices the brain of your voice agent by the minute: the LLM line on its pricing page runs from $0.045 to $0.16 per minute for frontier models, on top of the voice engine. Retell also has a custom LLM slot that skips that line entirely: it opens a WebSocket to your server during the call, streams the live transcript, and speaks whatever text you stream back. That slot is a clean fit for an open model on EcoHash. A small bridge server, about 90 lines, receives Retell's events and answers with streaming completions from &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;, which costs a fraction of a cent per call minute in tokens. This post walks through the protocol, the bridge, a local test that does not need a phone call, and the honest math.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Same agent, cheaper brain.&lt;/strong&gt; Retell's custom LLM slot plus a 90-line bridge puts an open model behind your voice agent for well under a cent per minute in tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What you are wiring together
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Retell slot:&lt;/strong&gt; Custom LLM, WebSocket; Retell connects to your server per call&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol:&lt;/strong&gt; Retell sends transcript events; you stream back response events&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bridge:&lt;/strong&gt; &lt;a href="https://github.com/ecohash-ai/ecohash-examples/tree/main/integrations/retell" rel="noopener noreferrer"&gt;integrations/retell&lt;/a&gt; in ecohash-examples, about 90 lines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default model:&lt;/strong&gt; &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;, $0.10 in / $0.10 out per 1M tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measured on EcoHash:&lt;/strong&gt; 205 ms TTFT (p95), ~143 tokens/sec single stream&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What stays on Retell:&lt;/strong&gt; Voice engine, STT, TTS, telephony (their built-in providers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API base URL:&lt;/strong&gt; &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the pieces fit
&lt;/h2&gt;

&lt;p&gt;Retell does not call a chat completions URL directly. When a call starts, Retell opens a WebSocket to your server and the two sides exchange JSON events:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your server sends a config event and a first sentence to speak.&lt;/li&gt;
&lt;li&gt;When the caller finishes a turn, Retell sends &lt;code&gt;response_required&lt;/code&gt; with the live transcript and a &lt;code&gt;response_id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The bridge forwards the transcript to EcoHash &lt;code&gt;/v1/chat/completions&lt;/code&gt; with &lt;code&gt;stream: true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Each token delta goes back to Retell as a response event; a final &lt;code&gt;content_complete&lt;/code&gt; closes the turn. If the caller interrupts, a newer &lt;code&gt;response_id&lt;/code&gt; arrives and the stale reply is dropped.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The bridge
&lt;/h2&gt;

&lt;p&gt;The full server is in &lt;a href="https://github.com/ecohash-ai/ecohash-examples/tree/main/integrations/retell" rel="noopener noreferrer"&gt;integrations/retell/server.py&lt;/a&gt;. The core of it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.websocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/llm-websocket/{call_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;llm_websocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auto_reconnect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;call_details&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BEGIN_SENTENCE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content_complete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iter_json&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;interaction_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reminder_required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llama-3.1-8b-instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;to_messages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transcript&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
                &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;delta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content_complete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content_complete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it and expose it publicly (ngrok is fine for a first test):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi uvicorn openai
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ECOHASH_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;eco_...   &lt;span class="c"&gt;# create one at console.ecohash.com&lt;/span&gt;
uvicorn server:app &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key comes from the EcoHash console: &lt;a href="https://console.ecohash.com/" rel="noopener noreferrer"&gt;create a free account&lt;/a&gt;, open API Keys, create one, and copy the &lt;code&gt;eco_&lt;/code&gt; value into &lt;code&gt;ECOHASH_API_KEY&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%2Fnpxmq30hkg4hg93y9prr.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%2Fnpxmq30hkg4hg93y9prr.png" alt=" " width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Point the agent at it
&lt;/h2&gt;

&lt;p&gt;In the Retell dashboard, click Create an Agent, open &lt;strong&gt;Other options&lt;/strong&gt;, and pick &lt;strong&gt;Custom LLM&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%2Fd0tepje3r6hxz38k6wj9.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%2Fd0tepje3r6hxz38k6wj9.png" alt=" " width="800" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then set the Custom LLM URL to your bridge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wss://your-host.example.com/llm-websocket
&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%2Fspejzbqdkcr3scza9qpe.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%2Fspejzbqdkcr3scza9qpe.png" alt=" " width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Retell appends the call id and connects when a call starts. Note the cost estimate in the agent header: it now covers voice and telephony only, with no LLM line in it, which is the point of this post. Everything else about the agent, voice, transcriber, phone number, stays exactly as it was. Retell's own &lt;a href="https://docs.retellai.com/integrate-llm/setup-websocket-server" rel="noopener noreferrer"&gt;custom LLM setup guide&lt;/a&gt; covers the dashboard walkthrough in detail; this bridge is the part their guide leaves as an exercise, wired to an open model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test it without making a call
&lt;/h2&gt;

&lt;p&gt;The bridge speaks a documented protocol, so you can fake Retell from your terminal with a WebSocket client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;websockets&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;websockets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ws://localhost:8000/llm-websocket/test-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;          &lt;span class="c1"&gt;# config
&lt;/span&gt;        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# first sentence
&lt;/span&gt;        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;interaction_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transcript&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Do you deliver on weekends?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}]}))&lt;/span&gt;
        &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content_complete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We ran this exact loop while writing the post: the bridge answered the config handshake, spoke its first sentence, and streamed a coherent 18-chunk reply from &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;, with ping and interrupt handling working as documented.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;With Retell's built-in models, the LLM is billed per minute. With a custom LLM, that line drops off Retell's bill and you pay your own provider per token instead. List prices, checked 2026-07-23:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GPT 5.5 via Retell:&lt;/strong&gt; $0.16&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPT 5.4 or Claude 4.6 Sonnet via Retell:&lt;/strong&gt; $0.08&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPT 4.1 via Retell:&lt;/strong&gt; $0.045&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;llama-3.1-8b-instruct on EcoHash via bridge:&lt;/strong&gt; ~$0.0003 in tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The EcoHash figure assumes a typical support call burns about 2,000 input and 250 output tokens per minute at $0.10 per 1M each; even a context-heavy agent at ten times that usage stays under a cent. Retell's other lines, the voice engine at $0.055 per minute plus TTS and telephony, are unchanged, so the saving applies to the LLM line only. You also take on hosting a small server, which is the real trade.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trade-offs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The custom LLM slot covers the brain only. Retell's STT and TTS stay on its built-in providers, so you cannot plug EcoHash's Kokoro in here. For that pattern, Vapi has an open TTS slot: see &lt;a href="https://ecohash.com/blog/vapi-custom-tts-kokoro" rel="noopener noreferrer"&gt;Give your Vapi voice agent a cheaper voice&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You are hosting a WebSocket server on the call path. Keep it close to Retell's region and return the first token fast; &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt; measures 205 ms TTFT (p95) on EcoHash, and your hosting adds on top. Measure before promising numbers.&lt;/li&gt;
&lt;li&gt;Voice replies should be short. Keep the system prompt strict about one-sentence answers or the agent will monologue.&lt;/li&gt;
&lt;li&gt;The cost table uses list prices as of the date above and stated token assumptions. Recheck both before building a business case.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does Retell support an OpenAI-compatible base URL directly?&lt;/strong&gt; No. The custom LLM slot is a WebSocket protocol, not a base URL field, which is why you run a small bridge. The bridge in this post is about 90 lines and the protocol is documented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which models can the bridge use?&lt;/strong&gt; Any chat model on EcoHash. &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt; is a good default for voice; &lt;code&gt;gpt-oss-20b&lt;/code&gt; adds capability at $0.05 in / $0.18 out per 1M tokens. See &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;/models&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens when the caller interrupts?&lt;/strong&gt; Retell sends a new &lt;code&gt;response_required&lt;/code&gt; with a higher &lt;code&gt;response_id&lt;/code&gt;. The bridge tracks the latest id and drops any reply still streaming for an older one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I add tool calls or RAG?&lt;/strong&gt; Yes, that is the point of owning the bridge: run retrieval, call tools, or apply guardrails between the transcript and the model. The same key also serves &lt;code&gt;/v1/embeddings&lt;/code&gt; and a reranker for RAG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does this change Retell's voice quality or latency budget?&lt;/strong&gt; Voice stays on Retell's engine. Your contribution to latency is bridge hosting plus model TTFT, so host near Retell and pick a fast model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I transcribe or analyze calls afterwards?&lt;/strong&gt; Use EcoHash &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; on the recordings and a chat model for summaries, on the same API key. See &lt;a href="https://ecohash.com/blog/kokoro-whisper-voice-agent" rel="noopener noreferrer"&gt;Build a voice agent with Whisper, Kokoro, and an OpenAI-compatible API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a free EcoHash API key: &lt;a href="https://console.ecohash.com/" rel="noopener noreferrer"&gt;console.ecohash.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bridge source: &lt;a href="https://github.com/ecohash-ai/ecohash-examples/tree/main/integrations/retell" rel="noopener noreferrer"&gt;integrations/retell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Browse chat models and prices: &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;/models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Vapi version of this pattern, for the voice side: &lt;a href="https://ecohash.com/blog/vapi-custom-tts-kokoro" rel="noopener noreferrer"&gt;/blog/vapi-custom-tts-kokoro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LLM benchmarks: &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks" rel="noopener noreferrer"&gt;ecohash-benchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Give your Vapi voice agent a cheaper voice: Kokoro TTS via custom-voice</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Mon, 12 Oct 2026 08:16:59 +0000</pubDate>
      <link>https://dev.to/ecohash/give-your-vapi-voice-agent-a-cheaper-voice-kokoro-tts-via-custom-voice-1onb</link>
      <guid>https://dev.to/ecohash/give-your-vapi-voice-agent-a-cheaper-voice-kokoro-tts-via-custom-voice-1onb</guid>
      <description>&lt;p&gt;Vapi lets you swap the voice of an agent for any TTS you want through its custom-voice provider: it POSTs the text to your server and plays back whatever PCM you return. That makes it a clean slot for Kokoro on EcoHash, an open 82M-parameter TTS that costs about $0.006 per minute of generated speech and returns first audio in roughly 120 ms. The whole integration is one small adapter server, about 60 lines: it receives Vapi's &lt;code&gt;voice-request&lt;/code&gt;, calls EcoHash's OpenAI-compatible &lt;code&gt;/v1/audio/speech&lt;/code&gt;, resamples to the rate Vapi asks for, and sends the raw PCM back. This post walks through the adapter, the assistant config, a local test that does not need a phone call, and the per-minute math against ElevenLabs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Swap the voice, keep the agent.&lt;/strong&gt; A 60-line adapter puts Kokoro behind Vapi at about $0.006 per minute of speech, roughly 7x below ElevenLabs Flash list price.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Teams running voice agents on Vapi who want to cut the TTS line item.&lt;/li&gt;
&lt;li&gt;Developers who want an open TTS model behind their agent instead of a proprietary voice.&lt;/li&gt;
&lt;li&gt;Anyone comparing per-minute costs across TTS providers before scaling outbound calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you can build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Vapi assistant that speaks with Kokoro at a fraction of the usual TTS cost.&lt;/li&gt;
&lt;li&gt;The same adapter pattern for any OpenAI-compatible TTS endpoint.&lt;/li&gt;
&lt;li&gt;A post-call pipeline that also transcribes recordings with &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; on the same API key.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Facts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TTS model:&lt;/strong&gt; &lt;code&gt;kokoro-82m&lt;/code&gt;, open weights, served on EcoHash&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Price:&lt;/strong&gt; $1 per 1M audio tokens, about $0.006 per minute of speech&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;First audio:&lt;/strong&gt; ~120 ms measured end-to-end on EcoHash&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vapi slot:&lt;/strong&gt; &lt;code&gt;custom-voice&lt;/code&gt; provider, HTTP POST, raw PCM response&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sample rates:&lt;/strong&gt; Vapi requests 8000, 16000, 22050, or 24000 Hz; Kokoro is 24 kHz native&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adapter:&lt;/strong&gt; &lt;a href="https://github.com/ecohash-ai/ecohash-examples/tree/main/integrations/vapi" rel="noopener noreferrer"&gt;integrations/vapi&lt;/a&gt; in ecohash-examples&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API base URL:&lt;/strong&gt; &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the pieces fit
&lt;/h2&gt;

&lt;p&gt;Vapi does not call EcoHash directly, because its custom-voice contract is not the OpenAI speech API. When the agent needs to speak, Vapi POSTs a JSON &lt;code&gt;voice-request&lt;/code&gt; with the text and a target sample rate, and expects headerless 16-bit mono PCM back at exactly that rate. So you run a small adapter in the middle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Vapi POSTs &lt;code&gt;{"message": {"type": "voice-request", "text": ..., "sampleRate": ...}}&lt;/code&gt; to your server.&lt;/li&gt;
&lt;li&gt;The adapter calls EcoHash &lt;code&gt;/v1/audio/speech&lt;/code&gt; with &lt;code&gt;model: kokoro-82m&lt;/code&gt; and &lt;code&gt;response_format: pcm&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Kokoro returns 24 kHz PCM; the adapter resamples if Vapi asked for a different rate.&lt;/li&gt;
&lt;li&gt;The adapter answers with &lt;code&gt;application/octet-stream&lt;/code&gt; PCM, and the caller hears Kokoro.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvb0vmfc5ph0qrnsa46vc.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%2Fvb0vmfc5ph0qrnsa46vc.png" alt=" " width="799" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The adapter
&lt;/h2&gt;

&lt;p&gt;The full server is in &lt;a href="https://github.com/ecohash-ai/ecohash-examples/tree/main/integrations/vapi" rel="noopener noreferrer"&gt;integrations/vapi/server.py&lt;/a&gt;. The core of it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/synthesize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;synthesize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;VAPI_SECRET&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x-vapi-secret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;VAPI_SECRET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;sample_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sampleRate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AsyncClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.ecohash.com/v1/audio/speech&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ECOHASH_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kokoro-82m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;voice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;af_heart&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_format&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pcm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;pcm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;resample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sample_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pcm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;media_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/octet-stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it and expose it publicly (ngrok is fine for a first test):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi uvicorn httpx numpy
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ECOHASH_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;eco_...          &lt;span class="c"&gt;# create one at console.ecohash.com&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;VAPI_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-webhook-secret
uvicorn server:app &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key comes from the EcoHash console: open API Keys, create one, and copy the &lt;code&gt;eco_&lt;/code&gt; value into &lt;code&gt;ECOHASH_API_KEY&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%2F006t0yrgkx0db2h5uf4t.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%2F006t0yrgkx0db2h5uf4t.png" alt=" " width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Point the assistant at it
&lt;/h2&gt;

&lt;p&gt;In your assistant config, set the voice to the custom-voice provider with your adapter's URL:&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;"voice"&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;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"custom-voice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"server"&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;"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;"https://your-host.example.com/synthesize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"your-webhook-secret"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"timeoutSeconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&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="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;If you prefer the dashboard, it is the same three fields under Assistant → Voice: set the provider to Custom voice and paste your adapter's &lt;code&gt;/synthesize&lt;/code&gt; URL.&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%2Fqgbpvtg4fprsm9lt4sg4.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%2Fqgbpvtg4fprsm9lt4sg4.png" alt=" " width="800" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vapi sends the secret back in the &lt;code&gt;x-vapi-secret&lt;/code&gt; header on every request, and the adapter rejects anything that does not match.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test it without making a call
&lt;/h2&gt;

&lt;p&gt;You can verify the whole path from your terminal by sending the same request Vapi would:&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/synthesize &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;"x-vapi-secret: your-webhook-secret"&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;'{"message":{"type":"voice-request","text":"Your order number seven two nine is confirmed.","sampleRate":16000}}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; reply.pcm

ffplay &lt;span class="nt"&gt;-f&lt;/span&gt; s16le &lt;span class="nt"&gt;-ar&lt;/span&gt; 16000 &lt;span class="nt"&gt;-ch_layout&lt;/span&gt; mono reply.pcm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We ran this exact loop while writing the post, at 8, 16, and 24 kHz, and fed the resampled PCM back into &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; on EcoHash. The transcription came back word for word, so the resampling holds up at telephony rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it costs
&lt;/h2&gt;

&lt;p&gt;Kokoro on EcoHash is billed at $1 per 1M audio tokens, and a second of generated speech is 100 tokens. One minute of speech is 6,000 tokens, or $0.006. List prices for the common alternatives, checked 2026-07-13:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kokoro on EcoHash&lt;/strong&gt; · List price: $1 / 1M audio tokens · Rough cost per audio minute: ~$0.006&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElevenLabs Flash/Turbo (API)&lt;/strong&gt; · List price: $0.05 / 1k characters · Rough cost per audio minute: ~$0.04&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElevenLabs Multilingual (API)&lt;/strong&gt; · List price: $0.10 / 1k characters · Rough cost per audio minute: ~$0.08&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The per-minute figures for ElevenLabs assume roughly 800 spoken characters per minute; your text and pacing will move them. Even so, the gap is around 7x to 13x, which adds up quickly on high-volume outbound calls. Voice quality is a judgment call: Kokoro is a small open model, so test it on your own scripts before switching production traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: run the brain on EcoHash too
&lt;/h2&gt;

&lt;p&gt;Vapi also supports a custom OpenAI-compatible LLM. In the dashboard, open your assistant's Model section, choose Custom LLM, and set the endpoint to &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt; with your EcoHash key as the API key and a model such as &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;. That puts the LLM and the voice on one provider and one bill; keep replies short in the system prompt so turns stay snappy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Live call transcription stays on Vapi's built-in transcribers. Vapi's custom transcriber slot expects a streaming WebSocket, and EcoHash's transcription endpoint is batch. Use EcoHash &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; for post-call transcription instead.&lt;/li&gt;
&lt;li&gt;Latency depends on where you host the adapter. Kokoro's first audio is ~120 ms measured end-to-end on EcoHash; keep the adapter close to your region and the total stays comfortable for calls, but measure your own setup before promising numbers.&lt;/li&gt;
&lt;li&gt;The cost table uses list prices on their published pages as of the date above. Recheck before you build a business case on them.&lt;/li&gt;
&lt;li&gt;Model IDs and voices change. Confirm &lt;code&gt;kokoro-82m&lt;/code&gt; and the voice list on &lt;a href="https://ecohash.com/models/kokoro-82m" rel="noopener noreferrer"&gt;/models/kokoro-82m&lt;/a&gt; before you build.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can Vapi use any TTS provider?&lt;/strong&gt; Yes, through the custom-voice provider. Vapi POSTs the text to your server and plays whatever PCM you return, so anything with a synthesis API works behind a small adapter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do I need an adapter at all?&lt;/strong&gt; Vapi's custom-voice contract is its own JSON request and raw PCM response, not the OpenAI speech API. The adapter translates between the two and resamples the audio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What sample rate should I return?&lt;/strong&gt; Exactly what Vapi asks for in &lt;code&gt;sampleRate&lt;/code&gt;. The adapter in this post resamples Kokoro's 24 kHz output to 8000, 16000, or 22050 Hz when needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does Kokoro cost on EcoHash?&lt;/strong&gt; $1 per 1M audio tokens, which is about $0.006 per minute of generated speech. See &lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;/pricing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I also do speech-to-text on EcoHash for Vapi calls?&lt;/strong&gt; Not live: Vapi's custom transcriber needs streaming input. For recordings and post-call analysis, &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt; on the same key works well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which voices does Kokoro have?&lt;/strong&gt; Several; this post uses &lt;code&gt;af_heart&lt;/code&gt;. See &lt;a href="https://ecohash.com/models/kokoro-82m" rel="noopener noreferrer"&gt;/models/kokoro-82m&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Adapter source: &lt;a href="https://github.com/ecohash-ai/ecohash-examples/tree/main/integrations/vapi" rel="noopener noreferrer"&gt;integrations/vapi&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Kokoro on EcoHash: &lt;a href="https://ecohash.com/models/kokoro-82m" rel="noopener noreferrer"&gt;/models/kokoro-82m&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Voice and speech on EcoHash: &lt;a href="https://ecohash.com/use-cases/voice-speech" rel="noopener noreferrer"&gt;/use-cases/voice-speech&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Speech benchmarks: &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks" rel="noopener noreferrer"&gt;ecohash-benchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Build a voice agent with Whisper, Kokoro, and an OpenAI-compatible API</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Sat, 10 Oct 2026 07:03:48 +0000</pubDate>
      <link>https://dev.to/ecohash/build-a-voice-agent-with-whisper-kokoro-and-an-openai-compatible-api-1ee</link>
      <guid>https://dev.to/ecohash/build-a-voice-agent-with-whisper-kokoro-and-an-openai-compatible-api-1ee</guid>
      <description>&lt;p&gt;A voice agent turns speech into speech: it transcribes what the user says, sends the text to a language model, and speaks the reply back. On EcoHash you build all three stages through one OpenAI-compatible API and one key, so there are no three vendors and no three billing accounts to stitch together. Whisper (&lt;code&gt;whisper-large-v3-turbo&lt;/code&gt;) does speech to text, a chat model such as &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt; writes the reply, and Kokoro (&lt;code&gt;kokoro-82m&lt;/code&gt;) turns it into audio. None of it needs a GPU of your own, since the models are served for you. This post walks through the pipeline, the three API calls, and when an RTX Pro 6000 workspace is worth it for heavier voice work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Three API calls, one key.&lt;/strong&gt; Whisper hears, a chat model thinks, Kokoro speaks. About $0.006 per minute of generated speech.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Developers building a voice assistant, an IVR replacement, or a spoken interface for an app.&lt;/li&gt;
&lt;li&gt;Teams that want speech to text, an LLM, and text to speech from one provider rather than three.&lt;/li&gt;
&lt;li&gt;Anyone prototyping a voice feature before deciding on dedicated capacity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you can build
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A back-and-forth voice assistant that listens, thinks, and speaks.&lt;/li&gt;
&lt;li&gt;A transcription-plus-reply feature inside an existing app.&lt;/li&gt;
&lt;li&gt;A spoken front end for a chatbot you already run on EcoHash.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How a voice agent works
&lt;/h2&gt;

&lt;p&gt;The loop has three stages, and each maps to one EcoHash endpoint:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Speech to text. The user's audio goes to Whisper, which returns text. This is the transcription endpoint.&lt;/li&gt;
&lt;li&gt;LLM. The text goes to a chat model, which returns a reply. This is the chat completions endpoint.&lt;/li&gt;
&lt;li&gt;Text to speech. The reply goes to Kokoro, which returns audio you play back. This is the speech endpoint.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then you repeat for the next turn. The whole loop uses one key and one base URL, so the three stages share auth, billing, and SDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  The models
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speech to text&lt;/strong&gt; · Model: Whisper Large V3 Turbo · Model ID: &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech to text (alt)&lt;/strong&gt; · Model: Qwen3 ASR · Model ID: &lt;code&gt;qwen3-asr-1-7b&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM&lt;/strong&gt; · Model: Llama 3.1 8B Instruct · Model ID: &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text to speech&lt;/strong&gt; · Model: Kokoro 82M · Model ID: &lt;code&gt;kokoro-82m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text to speech (alt)&lt;/strong&gt; · Model: Qwen3 TTS · Model ID: &lt;code&gt;qwen3-tts&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use a small or mid-size chat model for the LLM stage so replies come back fast. A coding-specialized model is the wrong pick for general conversation.&lt;/p&gt;

&lt;p&gt;Here is what the speech models measure on a single RTX Pro 6000, end-to-end, in July 2026. Speech to text:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;qwen3-asr-1-7b&lt;/strong&gt; · WER %: 3.28 · Peak RTFx: 360 · Price: input $0.05/1M&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;whisper-large-v3&lt;/strong&gt; · WER %: 3.64 · Peak RTFx: 45 · Price: $0.006/min&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;whisper-large-v3-turbo&lt;/strong&gt; · WER %: 4.37 · Peak RTFx: 59 · Price: $0.006/min&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Text to speech:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;kokoro-82m&lt;/strong&gt; · TTFA: 120 ms · Price: $1/1M&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;qwen3-tts&lt;/strong&gt; · TTFA: 2621 ms · Price: $2/1M&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the HF Open ASR Leaderboard, the models EcoHash serves land among the accurate ones (purple = served on EcoHash):&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%2F2mf1cee974ti2we3nuj1.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%2F2mf1cee974ti2we3nuj1.png" alt=" " width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full data and method: &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks" rel="noopener noreferrer"&gt;ecohash-benchmarks&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three API calls
&lt;/h2&gt;

&lt;p&gt;The API is OpenAI-compatible, so the OpenAI SDK works once you set the base URL and key. One client covers all three stages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.ecohash.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eco_...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# create a key at console.ecohash.com
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Speech to text
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input.wav&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;transcript&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transcriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;whisper-large-v3-turbo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="c1"&gt;# 2. LLM reply
&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;llama-3.1-8b-instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a concise voice assistant. Keep replies short.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Text to speech
&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;speech&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with_streaming_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kokoro-82m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;voice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;af_heart&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;response_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wav&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;speech&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;speech&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reply.wav&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You said:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Assistant:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a full single-turn voice agent. For multi-turn, keep the message history and run the loop again for each new audio input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running it without a GPU
&lt;/h2&gt;

&lt;p&gt;You do not need one. All three models are served through the API, so you can build and run a voice agent with no hardware to provision, and Kokoro in particular is small enough that it never needs an RTX Pro 6000.&lt;/p&gt;

&lt;p&gt;A workspace helps later, not at the start: when you want to co-locate a heavier speech-to-text, LLM, and text-to-speech pipeline on one card, push higher throughput, or run your own serving stack. That is a scaling choice. See &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;/gpu-compute&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This post does not promise real-time or a specific latency. End-to-end voice latency depends on network, the models you pick, whether you stream, and your own pipeline. Measure it on your setup and cite the method and date for any number you publish.&lt;/li&gt;
&lt;li&gt;Whisper and Kokoro do not require an RTX Pro 6000. They run through the API and move onto GPU capacity only when throughput demands it.&lt;/li&gt;
&lt;li&gt;The example is request-response. A production voice agent adds streaming audio, voice activity detection, turn-taking, and barge-in, which are your application's job.&lt;/li&gt;
&lt;li&gt;Model IDs and voices change. Confirm them on &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;/models&lt;/a&gt;, &lt;a href="https://ecohash.com/models/whisper-large-v3-turbo" rel="noopener noreferrer"&gt;/models/whisper-large-v3-turbo&lt;/a&gt;, and &lt;a href="https://ecohash.com/models/kokoro-82m" rel="noopener noreferrer"&gt;/models/kokoro-82m&lt;/a&gt; before you build.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is a voice agent?&lt;/strong&gt; A system that listens, thinks, and speaks: speech to text, then an LLM, then text to speech. The user talks, and the agent replies in audio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which models do I need?&lt;/strong&gt; Three: a speech-to-text model like &lt;code&gt;whisper-large-v3-turbo&lt;/code&gt;, a chat model like &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;, and a text-to-speech model like &lt;code&gt;kokoro-82m&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I do all of it with one API key?&lt;/strong&gt; Yes. On EcoHash the transcription, chat, and speech endpoints share one base URL and one key, so there is no three-vendor integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need an RTX Pro 6000 to run Kokoro or Whisper?&lt;/strong&gt; No. Both run through the API. A workspace is optional, for co-locating a heavier pipeline or higher throughput.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it fast enough for real-time conversation?&lt;/strong&gt; That depends on your network, model choices, streaming, and pipeline. This post does not publish latency numbers; measure your own setup before relying on a target.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which voices does Kokoro support?&lt;/strong&gt; Several; the example uses &lt;code&gt;af_heart&lt;/code&gt;. See &lt;a href="https://ecohash.com/models/kokoro-82m" rel="noopener noreferrer"&gt;/models/kokoro-82m&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does a voice agent cost?&lt;/strong&gt; The LLM stage is billed per token, and the audio stages by what they process. See &lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;/pricing&lt;/a&gt; for current rates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which chat model should I use for the LLM stage?&lt;/strong&gt; A small or mid-size general model keeps replies quick. See &lt;a href="https://ecohash.com/blog/best-models-for-rtx-pro-6000" rel="noopener noreferrer"&gt;Best models to run on RTX Pro 6000 96GB&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;See voice and speech on EcoHash: &lt;a href="https://ecohash.com/use-cases/voice-speech" rel="noopener noreferrer"&gt;/use-cases/voice-speech&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Speech-to-text model: &lt;a href="https://ecohash.com/models/whisper-large-v3-turbo" rel="noopener noreferrer"&gt;/models/whisper-large-v3-turbo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Text-to-speech model: &lt;a href="https://ecohash.com/models/kokoro-82m" rel="noopener noreferrer"&gt;/models/kokoro-82m&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Browse all models: &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;/models&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>agents</category>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
    </item>
    <item>
      <title>Qwen3 Coder 30B on RTX Pro 6000: API, dedicated endpoint, or GPU workspace?</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Tue, 29 Sep 2026 03:48:15 +0000</pubDate>
      <link>https://dev.to/ecohash/qwen3-coder-30b-on-rtx-pro-6000-api-dedicated-endpoint-or-gpu-workspace-3eg8</link>
      <guid>https://dev.to/ecohash/qwen3-coder-30b-on-rtx-pro-6000-api-dedicated-endpoint-or-gpu-workspace-3eg8</guid>
      <description>&lt;p&gt;Three ways to run Qwen3 Coder 30B (&lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;), and the right one comes down to your traffic and how much control you want. The shared OpenAI-compatible API gets you a first call in minutes and bills per token, which fits prototypes and bursty traffic. A dedicated endpoint reserves capacity for steadier throughput and predictable latency in production, still with no GPU to manage. An hourly RTX Pro 6000 workspace gives you the whole card for fine-tuning, batch jobs, or your own serving stack. The model and the API contract are the same across all three, so moving up later does not mean a rewrite.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Same model, three ways to run it.&lt;/strong&gt; Start on the per-token API, reserve a dedicated endpoint for production, rent the card itself for fine-tuning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Facts
&lt;/h2&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;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Qwen3 Coder 30B (&lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mixture-of-Experts, about 30B total parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context served&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;32,768 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API price&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;input $0.10 / output $0.30 per 1M tokens (&lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPU workspace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;RTX Pro 6000 at $1.89/GPU-hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API base URL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hugging Face&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Qwen/Qwen3-Coder-30B-A3B-Instruct&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On a single RTX Pro 6000, end-to-end, we measure it at 30 ms to first token and 9 ms per output token, about 110 tokens per second on a single stream (July 2026). A responsive coding assistant lives or dies on time to first token, and in a same-model provider comparison (&lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt; across providers, EcoHash in purple) it comes in lowest in the field:&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%2Fk476pgjmpjwsma5b1kqo.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%2Fk476pgjmpjwsma5b1kqo.jpg" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;br&gt;
Full data, method, and charts: &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks" rel="noopener noreferrer"&gt;ecohash-benchmarks&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Developers adding Qwen3 Coder to a coding assistant, an agent, or a code-review tool.&lt;/li&gt;
&lt;li&gt;Teams deciding whether to call a shared API, reserve capacity, or run their own GPU.&lt;/li&gt;
&lt;li&gt;Anyone moving a Qwen3 Coder prototype toward steady production traffic.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What you can decide
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Which of the three paths fits your current stage.&lt;/li&gt;
&lt;li&gt;What changes and what stays the same when you move between them.&lt;/li&gt;
&lt;li&gt;When it is worth reserving a dedicated endpoint or renting a workspace.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The shared API
&lt;/h2&gt;

&lt;p&gt;The shared API serves Qwen3 Coder through an OpenAI-compatible endpoint at &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;. You send a request, get a completion, and pay per token. There is no GPU to provision and no capacity to plan, and because traffic runs on shared infrastructure, latency moves with overall load.&lt;/p&gt;

&lt;p&gt;This is where most projects should start, and it suits bursty traffic well since you pay for what you use rather than for reserved capacity. See &lt;a href="https://ecohash.com/inference" rel="noopener noreferrer"&gt;inference&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The dedicated endpoint
&lt;/h2&gt;

&lt;p&gt;A dedicated endpoint reserves capacity for Qwen3 Coder so your traffic is not competing with anyone else's. You still call the same API and still manage no GPU. What you gain is steadier throughput and more predictable latency, which starts to matter once a coding feature is in production and people expect consistent response times.&lt;/p&gt;

&lt;p&gt;Reach for it when your traffic is steady and high enough that predictability is worth reserving capacity for. See &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;dedicated inference&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The GPU workspace
&lt;/h2&gt;

&lt;p&gt;A GPU workspace is an RTX Pro 6000 you rent by the hour at $1.89/GPU-hour. You get the whole card and control of the environment, so you can run a custom serving stack such as vLLM or SGLang, fine-tune with LoRA or QLoRA, or run batch jobs. Qwen3 Coder 30B fits on one 96 GB card with room for context and batching.&lt;/p&gt;

&lt;p&gt;Reach for it when the API and dedicated endpoints do not give you enough control, or when the work is not request-response serving at all, like fine-tuning or offline batch generation. See &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;GPU compute&lt;/a&gt; and &lt;a href="https://ecohash.com/fine-tuning" rel="noopener noreferrer"&gt;fine-tuning&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  How the three compare
&lt;/h2&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;Shared API&lt;/th&gt;
&lt;th&gt;Dedicated endpoint&lt;/th&gt;
&lt;th&gt;GPU workspace&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What it is&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Call the model over the API&lt;/td&gt;
&lt;td&gt;Reserved capacity for the model&lt;/td&gt;
&lt;td&gt;Rent the RTX Pro 6000 by the hour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;You manage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Nothing&lt;/td&gt;
&lt;td&gt;Nothing&lt;/td&gt;
&lt;td&gt;The environment and serving stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;How you pay&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per token&lt;/td&gt;
&lt;td&gt;Reserved capacity&lt;/td&gt;
&lt;td&gt;Per GPU-hour ($1.89)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Varies with shared load&lt;/td&gt;
&lt;td&gt;Steadier, more predictable&lt;/td&gt;
&lt;td&gt;The full card is yours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Elastic&lt;/td&gt;
&lt;td&gt;Reserved throughput&lt;/td&gt;
&lt;td&gt;One card, or more on request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prototypes, spiky traffic&lt;/td&gt;
&lt;td&gt;Steady production traffic&lt;/td&gt;
&lt;td&gt;Fine-tuning, batch, custom serving&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Where&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ecohash.com/inference" rel="noopener noreferrer"&gt;inference&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;dedicated inference&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;GPU compute&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The model ID and the API contract hold across the first two, and the same model runs in the workspace, so moving between them does not force a rewrite.&lt;/p&gt;
&lt;h2&gt;
  
  
  Calling Qwen3 Coder
&lt;/h2&gt;

&lt;p&gt;The API is OpenAI-compatible, so existing OpenAI SDK code works once you change the base URL and key. The same call works on the shared API or a dedicated endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.ecohash.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eco_...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# create a key at console.ecohash.com
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qwen3-coder-30b-a3b-instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a Python function that parses an ISO 8601 timestamp into a datetime.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.ecohash.com/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;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_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="s2"&gt;"Content-Type: application/json"&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": "qwen3-coder-30b-a3b-instruct",
    "messages": [{"role": "user", "content": "Write a Python function that parses an ISO 8601 timestamp into a datetime."}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to move up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prototype and early traffic:&lt;/strong&gt; shared API. You are still changing prompts and shipping features, and per-token billing keeps cost tied to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent production traffic:&lt;/strong&gt; dedicated endpoint. Once users notice latency and volume is steady, reserved capacity buys predictability without infrastructure work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full control or non-serving work:&lt;/strong&gt; GPU workspace. Fine-tuning, batch generation, and custom serving need the card itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You do not choose once. Plenty of teams run the API in development, a dedicated endpoint in production, and spin up a workspace only when they fine-tune.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The context served here is 32,768 tokens. Do not assume a larger window unless it is confirmed for this deployment.&lt;/li&gt;
&lt;li&gt;Performance depends on quantization, batch size, and context length. Reproduce any figure with its method and date.&lt;/li&gt;
&lt;li&gt;Dedicated endpoint and workspace pricing depend on configuration. Check &lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt; and &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;dedicated inference&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Model IDs change as the catalog changes. Confirm &lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt; on &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;the model catalog&lt;/a&gt; before you build.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I run Qwen3 Coder 30B on an RTX Pro 6000?&lt;/strong&gt; Yes. It is a Mixture-of-Experts model with about 30B total parameters and fits on one 96 GB RTX Pro 6000 with room for context and batching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between the API and a dedicated endpoint?&lt;/strong&gt; Both use the same OpenAI-compatible API and neither asks you to manage a GPU. The shared API bills per token on shared infrastructure; a dedicated endpoint reserves capacity for steadier throughput and more predictable latency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When should I rent a GPU workspace instead?&lt;/strong&gt; When you need the whole card: fine-tuning with LoRA or QLoRA, batch generation, or a custom serving stack such as vLLM or SGLang.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What context length does Qwen3 Coder have here?&lt;/strong&gt; 32,768 tokens as served.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does Qwen3 Coder cost?&lt;/strong&gt; Through the API, $0.10 per 1M input tokens and $0.30 per 1M output tokens. A GPU workspace is $1.89/GPU-hour. See &lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt; for current rates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I have to change my code to switch paths?&lt;/strong&gt; No. The model ID and API contract stay the same across the shared API and a dedicated endpoint, and the same model runs in a workspace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which models pair well with Qwen3 Coder for a coding product?&lt;/strong&gt; See &lt;a href="https://ecohash.com/blog/best-models-for-rtx-pro-6000" rel="noopener noreferrer"&gt;Best models to run on RTX Pro 6000 96GB&lt;/a&gt; for embeddings, rerankers, and chat models that share the same key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;See the model page: &lt;a href="https://ecohash.com/models/qwen3-coder-30b-a3b-instruct" rel="noopener noreferrer"&gt;Qwen3 Coder 30B&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Start on the shared API: &lt;a href="https://ecohash.com/inference" rel="noopener noreferrer"&gt;ecohash.com/inference&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reserve a dedicated endpoint: &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;ecohash.com/dedicated-inference&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rent an RTX Pro 6000: &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;ecohash.com/gpu-compute&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
    </item>
    <item>
      <title>What makes RTX Pro 6000 96GB a good GPU for AI inference?</title>
      <dc:creator>Ecohash</dc:creator>
      <pubDate>Wed, 23 Sep 2026 01:47:33 +0000</pubDate>
      <link>https://dev.to/ecohash/what-makes-rtx-pro-6000-96gb-a-good-gpu-for-ai-inference-30a1</link>
      <guid>https://dev.to/ecohash/what-makes-rtx-pro-6000-96gb-a-good-gpu-for-ai-inference-30a1</guid>
      <description>&lt;p&gt;The RTX Pro 6000 Blackwell Server Edition gives you 96 GB of GDDR7 on one card, and for inference that capacity is the whole point. 96 GB holds a 20B to 35B open model with room left for KV cache and larger batches, so you serve it on a single GPU instead of splitting it across several. In the size range most teams actually deploy, that keeps both latency and operations simpler. On EcoHash the same card backs three ways to use it, a shared OpenAI-compatible API, a dedicated endpoint, and an hourly GPU workspace, and you move between them without changing the model or your code. It is a strong fit for mid-sized open models, and it is not the card for the very largest ones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;96 GB on one card. A 20B to 35B open model, its KV cache, and real batch sizes fit on a single GPU at $1.89 per hour.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Developers checking whether a single 96 GB card can host the open model they want to serve.&lt;/li&gt;
&lt;li&gt;Teams weighing a shared model API against dedicated or self-managed GPU capacity.&lt;/li&gt;
&lt;li&gt;Anyone sizing an RTX Pro 6000 for 20B to 35B models before spending on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What you can decide
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Whether your model fits on one card, or needs quantization or more GPUs.&lt;/li&gt;
&lt;li&gt;Which path fits your stage: shared API, dedicated endpoint, or workspace.&lt;/li&gt;
&lt;li&gt;When a model is large enough that a different GPU is the better call.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Facts
&lt;/h2&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;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hardware&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NVIDIA RTX Pro 6000 Blackwell Server Edition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;VRAM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;96 GB GDDR7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Architecture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Blackwell generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Interconnect&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PCIe (single-GPU and multi-instance inference)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best-fit models&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20B to 35B open models, plus selected quantized larger models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;EcoHash GPU price&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$1.89 per GPU-hour (&lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Access on EcoHash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Shared API, dedicated endpoint, GPU workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;API base URL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why 96 GB matters
&lt;/h2&gt;

&lt;p&gt;VRAM sets the ceiling on what you can serve. The weights have to fit, and so does the KV cache, which grows with batch size and context length. Once the weights eat most of the card, you are left with small batches, short context, or a model split across GPUs.&lt;/p&gt;

&lt;p&gt;96 GB changes that math for mid-sized models. A 30B-class model in a memory-efficient format still leaves room for concurrent requests and long prompts on one card, so you skip tensor-parallel serving and the latency and operational overhead that come with it. A 7B or 13B model has even more headroom, which you spend on bigger batches and longer context rather than leaving idle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blackwell, on a single card
&lt;/h2&gt;

&lt;p&gt;The RTX Pro 6000 is a Blackwell-generation card on PCIe. EcoHash runs it as single-GPU and multi-instance capacity rather than an NVLink cluster, which suits inference: one card serves one model, or hosts a few smaller ones side by side.&lt;/p&gt;

&lt;p&gt;Blackwell also handles the low-precision formats modern inference leans on, such as FP8, which lets a larger model fit in the same memory and can lift throughput. How much depends on the model and the serving stack, so treat the 96 GB as a fixed fact and treat quantization gains as something to measure on your own workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it compares to other inference GPUs
&lt;/h2&gt;

&lt;p&gt;These are published hardware specs, not our own benchmarks, and they are here for context.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GPU&lt;/th&gt;
&lt;th&gt;VRAM&lt;/th&gt;
&lt;th&gt;Interconnect&lt;/th&gt;
&lt;th&gt;Typical best fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RTX Pro 6000 (Blackwell)&lt;/td&gt;
&lt;td&gt;96 GB GDDR7&lt;/td&gt;
&lt;td&gt;PCIe&lt;/td&gt;
&lt;td&gt;Single-GPU serving of 20B to 35B models; headroom on smaller ones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RTX 6000 Ada (previous gen)&lt;/td&gt;
&lt;td&gt;48 GB GDDR6&lt;/td&gt;
&lt;td&gt;PCIe&lt;/td&gt;
&lt;td&gt;Smaller models, tighter memory budgets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L40S&lt;/td&gt;
&lt;td&gt;48 GB GDDR6&lt;/td&gt;
&lt;td&gt;PCIe&lt;/td&gt;
&lt;td&gt;Cost-focused serving of smaller models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;H100&lt;/td&gt;
&lt;td&gt;80 GB HBM3&lt;/td&gt;
&lt;td&gt;NVLink&lt;/td&gt;
&lt;td&gt;High-throughput and multi-GPU serving of large models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;H200&lt;/td&gt;
&lt;td&gt;141 GB HBM3e&lt;/td&gt;
&lt;td&gt;NVLink&lt;/td&gt;
&lt;td&gt;Very large models and long-context workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The H100 and H200 use HBM with higher bandwidth and NVLink, which favors large models and multi-GPU tensor parallelism. The RTX Pro 6000 trades some of that bandwidth for a large, cost-effective single-card budget, and it is at its best when the model fits on one card.&lt;/p&gt;

&lt;h2&gt;
  
  
  What fits on 96 GB
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model size&lt;/th&gt;
&lt;th&gt;Fit on one 96 GB card&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;7B to 13B&lt;/td&gt;
&lt;td&gt;Comfortable&lt;/td&gt;
&lt;td&gt;Room for large batches and long context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20B to 35B&lt;/td&gt;
&lt;td&gt;The sweet spot&lt;/td&gt;
&lt;td&gt;For example &lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;, &lt;code&gt;gpt-oss-20b&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Around 70B&lt;/td&gt;
&lt;td&gt;Case by case&lt;/td&gt;
&lt;td&gt;Usually needs quantization; validate first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;235B and above&lt;/td&gt;
&lt;td&gt;Not the target&lt;/td&gt;
&lt;td&gt;Use an H200 or a multi-GPU or partner path&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Model IDs are current EcoHash catalog IDs. See the &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;model catalog&lt;/a&gt; for the full list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measured numbers
&lt;/h2&gt;

&lt;p&gt;Numbers below are measured on a single RTX Pro 6000, end-to-end through the API, in July 2026. Full data, method, and charts are in &lt;a href="https://github.com/ecohash-ai/ecohash-benchmarks" rel="noopener noreferrer"&gt;ecohash-benchmarks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Text generation, single stream:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;TTFT (p95)&lt;/th&gt;
&lt;th&gt;Per-token&lt;/th&gt;
&lt;th&gt;Single-stream tok/s&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;205 ms&lt;/td&gt;
&lt;td&gt;7 ms&lt;/td&gt;
&lt;td&gt;~143&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-oss-20b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;170 ms&lt;/td&gt;
&lt;td&gt;8 ms&lt;/td&gt;
&lt;td&gt;~125&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;30 ms&lt;/td&gt;
&lt;td&gt;9 ms&lt;/td&gt;
&lt;td&gt;~111&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Under concurrency the card sustains about 11,500 output tok/s on &lt;code&gt;llama-3.1-8b-instruct&lt;/code&gt;. With 8k-token prompts, prefill reaches roughly 170k to 220k tok/s, which is why long-context and RAG are the most cost-effective way to use it. Against other providers of the same model, its time to first token is the lowest in the field:&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%2F1o7sx7ovjvpge8iodh17.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%2F1o7sx7ovjvpge8iodh17.png" alt="Llama-3.1-8B latency: EcoHash vs peers" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Image generation at 1024×1024:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Steps&lt;/th&gt;
&lt;th&gt;Latency&lt;/th&gt;
&lt;th&gt;Images/min&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;flux2-klein&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1.2 s&lt;/td&gt;
&lt;td&gt;52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;z-image-turbo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;3.2 s&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen-image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;13.4 s&lt;/td&gt;
&lt;td&gt;4.6&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Three ways to use it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Shared API.&lt;/strong&gt; Call open models through the OpenAI-compatible API at &lt;code&gt;https://api.ecohash.com/v1&lt;/code&gt;, with no GPU to manage. Good for building and for traffic that comes in bursts. See &lt;a href="https://ecohash.com/inference" rel="noopener noreferrer"&gt;inference&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedicated endpoint.&lt;/strong&gt; Reserve capacity for one model when production traffic needs steadier throughput and predictable latency. See &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;dedicated inference&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU workspace.&lt;/strong&gt; Rent the card by the hour for experiments, &lt;a href="https://ecohash.com/fine-tuning" rel="noopener noreferrer"&gt;fine-tuning&lt;/a&gt;, and batch jobs. See &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;GPU compute&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can start on the API and move to reserved capacity later without touching the model or the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling a model
&lt;/h2&gt;

&lt;p&gt;The API is OpenAI-compatible, so existing OpenAI SDK code works once you point the base URL and key at EcoHash.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.ecohash.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eco_...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# create a key at console.ecohash.com
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;qwen3-coder-30b-a3b-instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a Python function that reverses a linked list.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.ecohash.com/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;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$ECOHASH_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="s2"&gt;"Content-Type: application/json"&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": "qwen3-coder-30b-a3b-instruct",
    "messages": [{"role": "user", "content": "Write a Python function that reverses a linked list."}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Validating the fit
&lt;/h2&gt;

&lt;p&gt;Before you commit a model to this card:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check that the model plus KV cache fits in 96 GB at your context length and batch size.&lt;/li&gt;
&lt;li&gt;Pick a quantization format and compare its output against full precision on your own prompts.&lt;/li&gt;
&lt;li&gt;Choose a serving stack such as vLLM or SGLang and pin the version.&lt;/li&gt;
&lt;li&gt;Measure latency and throughput on your own traffic, and record the model revision, quantization, context length, framework, and driver so the numbers reproduce.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where it falls short
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;96 GB is a single-card budget. Models above roughly 70B usually need quantization or more than one GPU.&lt;/li&gt;
&lt;li&gt;Models at 235B and above are not the target. Use an H200 or a multi-GPU or partner path.&lt;/li&gt;
&lt;li&gt;We run the card as PCIe capacity, not an NVLink cluster, so workloads that lean on wide tensor parallelism see less benefit.&lt;/li&gt;
&lt;li&gt;Real numbers depend on the model, quantization, batch size, and context length. Treat any performance figure as something to reproduce with its method and date.&lt;/li&gt;
&lt;li&gt;Small and voice models do not need this card. They run through the API and move onto GPU capacity only when throughput calls for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is the RTX Pro 6000 good for AI inference?&lt;/strong&gt; Yes, for open models in the 20B to 35B range and for smaller models at higher batch sizes. Its 96 GB lets one card serve a mid-sized model with room for context and concurrency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much VRAM does the RTX Pro 6000 have?&lt;/strong&gt; 96 GB of GDDR7, on the Blackwell Server Edition that EcoHash deploys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does it differ from an H100 for inference?&lt;/strong&gt; The H100 has 80 GB of HBM with higher bandwidth and NVLink, which suits large models and multi-GPU serving. The RTX Pro 6000 has 96 GB of GDDR7 over PCIe, which suits single-GPU serving of 20B to 35B models at a lower hourly cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What models fit on a single RTX Pro 6000 96GB?&lt;/strong&gt; Open models up to about 35B, including &lt;code&gt;qwen3-coder-30b-a3b-instruct&lt;/code&gt; and &lt;code&gt;gpt-oss-20b&lt;/code&gt;. Models near 70B usually need quantization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can it run a 70B model?&lt;/strong&gt; Sometimes, with quantization and reduced context or batch size. Validate the specific model and settings before relying on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it support FP8 and other low-precision formats?&lt;/strong&gt; Blackwell supports the low-precision formats used in inference, including FP8. Confirm what your serving stack uses and check output quality before depending on it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does it cost on EcoHash?&lt;/strong&gt; $1.89 per GPU-hour. See &lt;a href="https://ecohash.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt; for the current rate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do voice or small models need it?&lt;/strong&gt; No. Models like Kokoro and Whisper run through the API, and move onto GPU capacity only when throughput demands it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Launch a GPU workspace: &lt;a href="https://ecohash.com/gpu-compute" rel="noopener noreferrer"&gt;ecohash.com/gpu-compute&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Browse open models: &lt;a href="https://ecohash.com/models" rel="noopener noreferrer"&gt;ecohash.com/models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Reserve steady capacity: &lt;a href="https://ecohash.com/dedicated-inference" rel="noopener noreferrer"&gt;ecohash.com/dedicated-inference&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




</description>
    </item>
  </channel>
</rss>
