<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Runai | The .NET Blog</title><link>https://thedotnetblog.com/tags/runai/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>en</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Fri, 04 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/tags/runai/index.xml" rel="self" type="application/rss+xml"/><item><title>Stop Wasting GPU Time: Stream LLM Weights Directly from Azure Blob Storage</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/eliminate-llm-cold-starts-blob-runai/</link><pubDate>Fri, 04 Sep 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/eliminate-llm-cold-starts-blob-runai/</guid><description>Run:AI Model Streamer cuts LLM cold starts from minutes to seconds by skipping the local disk hop. A practical look at performance, setup, and autoscaling.</description><content:encoded>&lt;p&gt;Original source: &lt;a href="https://devblogs.microsoft.com/azure-sdk/eliminate-llm-cold-starts-load-models-up-to-6x-faster-with-azure-blob-storage-and-runai-model-streamer/"&gt;Eliminate LLM Cold starts: Load models up to 6x Faster with Azure Blob Storage and Run:AI Model Streamer&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-real-cost-of-cold-starts"&gt;The Real Cost of Cold Starts&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re serving LLMs on Azure, you already know the pain: autoscaling adds a replica, but it sits idle while model weights copy from blob storage to disk and then into GPU memory. Every second of idle GPU time is money on the bill, and a queue is building under the traffic that triggered the scale-out.&lt;/p&gt;
&lt;p&gt;In the source benchmark, a 232.8 GiB model with the default vLLM loader took roughly 3 to 5 minutes to load on a Standard_ND96isr_H100_v5 VM. That delay can recur when an autoscaler adds a replica, a spot VM is reclaimed, a rolling deployment restarts a process, or a serving system swaps models.&lt;/p&gt;
&lt;p&gt;The default loader performs two sequential steps: download the model from Azure Blob Storage to local disk, then read it from disk into GPU memory. Run:AI Model Streamer removes the local disk hop. It streams model data through CPU memory into GPU memory, reducing the unavailable window in the benchmark from minutes to seconds.&lt;/p&gt;
&lt;h2 id="performance-that-fits-the-autoscaler"&gt;Performance That Fits the Autoscaler&lt;/h2&gt;
&lt;p&gt;The comparison used an 8x NVIDIA H100 machine streaming from Premium block blob storage in the same region. The results were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Meta-Llama-3.1-8B-Instruct, 14.99 GiB: 3.61 seconds with the streamer versus 15.48 seconds with the default loader, about 4.3x faster.&lt;/li&gt;
&lt;li&gt;GPT-OSS-120B, 60.8 GiB: 12.76 seconds versus 42.29 seconds, about 3.3x faster.&lt;/li&gt;
&lt;li&gt;Qwen3.5-122B-A10B, 232.8 GiB: 37.14 seconds versus 225.57 seconds, about 6.1x faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The streamer held a steady 80 Gbps in the benchmark. The default loader peaked around 40 Gbps and dropped as low as 10 Gbps on the largest model. The most important result is not just the speedup: the largest model loaded within one typical autoscaler cycle with the streamer, while the default loader did not.&lt;/p&gt;
&lt;p&gt;That changes the failure pattern. Existing replicas have less time to absorb the whole spike, queues are less likely to grow past gateway or client timeouts, and the next capacity decision has a better chance of seeing the new replica online. These are benchmark results, not a guarantee for every storage account or network path, so measure your own model and region.&lt;/p&gt;
&lt;h2 id="quick-start-with-vllm-or-sglang"&gt;Quick Start with vLLM or SGLang&lt;/h2&gt;
&lt;p&gt;Both vLLM and SGLang can stream weights from Azure Blob Storage through an &lt;code&gt;az://&lt;/code&gt; URI. First place SafeTensors weights in a blob container. The source uses &lt;code&gt;azcopy&lt;/code&gt; for upload and passes the storage account separately with &lt;code&gt;AZURE_STORAGE_ACCOUNT_NAME&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For vLLM:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv pip install vllm&lt;span class="o"&gt;[&lt;/span&gt;runai&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;AZURE_STORAGE_ACCOUNT_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;lt;your_account_name&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vllm serve az://&amp;lt;your-container&amp;gt;/models/llama-3.1-8b &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --load-format runai_streamer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For a multi-GPU deployment, the source shows tensor parallelism and distributed streaming:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;vllm serve az://&amp;lt;your-container&amp;gt;/models/llama-3.1-405b &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --load-format runai_streamer &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --tensor-parallel-size &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --model-loader-extra-config &lt;span class="s1"&gt;&amp;#39;{&amp;#34;distributed&amp;#34;: true, &amp;#34;concurrency&amp;#34;: 32}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SGLang follows the same pattern:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;uv pip install &lt;span class="s2"&gt;&amp;#34;sglang[runai]&amp;#34;&lt;/span&gt; --prerelease&lt;span class="o"&gt;=&lt;/span&gt;allow
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;python -m sglang.launch_server &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --model-path az://&amp;lt;your-container&amp;gt;/models/llama-3.1-8b &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --load-format runai_streamer &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --served-model-name llama-3.1-8b
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Authentication uses &lt;code&gt;DefaultAzureCredential&lt;/code&gt;, which supports local &lt;code&gt;az login&lt;/code&gt; and managed identity environments such as AKS, Azure ML, and VMs. That makes the serving path compatible with normal Azure identity practices rather than requiring a storage key in a startup script.&lt;/p&gt;
&lt;h2 id="tuning-and-caveats"&gt;Tuning and Caveats&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;RUNAI_STREAMER_CONCURRENCY&lt;/code&gt; controls concurrent I/O threads and defaults to 8 for object storage. The source suggests values such as 32 or 64 when the backend and network can use more parallelism. &lt;code&gt;RUNAI_STREAMER_MEMORY_LIMIT&lt;/code&gt; controls the CPU buffer cap.&lt;/p&gt;
&lt;p&gt;SafeTensors weights are required. If a model only contains &lt;code&gt;.bin&lt;/code&gt; files, convert or obtain a compatible format before testing the streamer. The 6x result is also a benchmark result on specific hardware, model sizes, storage, and region placement. Verify throughput, memory pressure, and failure behavior in your own environment.&lt;/p&gt;
&lt;p&gt;For .NET developers, the serving change is usually behind the application boundary. A .NET service may continue calling vLLM or SGLang over HTTP or gRPC, but shorter cold starts can change timeout and retry behavior. Revisit those settings after measuring the new startup profile; a client that was tuned for multi-minute loading may now retry too aggressively during a different failure mode.&lt;/p&gt;
&lt;h2 id="what-to-do-next"&gt;What to Do Next&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Measure current model load time and the autoscaler cadence for one representative workload.&lt;/li&gt;
&lt;li&gt;Upload a SafeTensors model to a same-region Premium blob account in a test environment.&lt;/li&gt;
&lt;li&gt;Compare the default loader and Run:AI Model Streamer under cold-start conditions.&lt;/li&gt;
&lt;li&gt;Tune concurrency only after checking network and CPU-buffer behavior.&lt;/li&gt;
&lt;li&gt;Update application timeouts and retry policies based on observed serving behavior.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The useful idea is simple: remove an unnecessary copy from object storage to local disk. For large models, that small architectural change can decide whether autoscaling feels like recovery or like another incident.&lt;/p&gt;</content:encoded></item></channel></rss>