<?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: kube-gopher</title>
    <description>The latest articles on DEV Community by kube-gopher (@kubegopher).</description>
    <link>https://dev.to/kubegopher</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%2F3967235%2F05843d56-4399-4d43-ac79-00620cc98d5a.jpeg</url>
      <title>DEV Community: kube-gopher</title>
      <link>https://dev.to/kubegopher</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kubegopher"/>
    <language>en</language>
    <item>
      <title>Introducing Hearth v0.3.0: Scale Long-Tail LLMs to Zero on Private Kubernetes</title>
      <dc:creator>kube-gopher</dc:creator>
      <pubDate>Mon, 20 Jul 2026 12:58:26 +0000</pubDate>
      <link>https://dev.to/kubegopher/introducing-hearth-v030-scale-long-tail-llms-to-zero-on-private-kubernetes-5blh</link>
      <guid>https://dev.to/kubegopher/introducing-hearth-v030-scale-long-tail-llms-to-zero-on-private-kubernetes-5blh</guid>
      <description>&lt;p&gt;**  An open-source, composable control plane for teams that want to stop paying the always-on cost of rarely used models.&lt;br&gt;
**&lt;br&gt;
  Hearth v0.3.0(&lt;a href="https://github.com/hearthproject/hearth/releases/tag/v0.3.0" rel="noopener noreferrer"&gt;https://github.com/hearthproject/hearth/releases/tag/v0.3.0&lt;/a&gt;) is now available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Most conversations about LLM serving focus on high-traffic models
&lt;/h2&gt;

&lt;p&gt;large fleets, complex routing, distributed inference, and maximum throughput. But many private Kubernetes clusters face a different problem.&lt;/p&gt;

&lt;p&gt;They have a limited pool of GPUs or NPUs, a handful of frequently used models, and a much longer tail of models that may receive only occasional requests. Keeping every model warm wastes expensive accelerator capacity. Scaling them down sounds simple—until the next request arrives.&lt;/p&gt;

&lt;p&gt;Setting a Deployment to zero replicas is easy. Preserving the first client request while Kubernetes schedules a Pod, pulls an image, loads model weights, passes readiness probes, and begins serving tokens is not. Safe scale-down is equally difficult when requests are still streaming.&lt;/p&gt;

&lt;p&gt;This is the lifecycle problem Hearth is designed to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Hearth?
&lt;/h2&gt;

&lt;p&gt;Hearth (&lt;a href="https://github.com/hearth-project/hearth" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth&lt;/a&gt;) is a minimal, composable LLM serving control plane for private Kubernetes clusters.&lt;/p&gt;

&lt;p&gt;It is not an inference engine and does not implement accelerator kernels. It does not install device plugins or replace Kubernetes schedulers. It is also not trying to become a fleet-level AI serving platform.&lt;/p&gt;

&lt;p&gt;Instead, Hearth owns the Kubernetes lifecycle between a model declaration and a working, scale-to-zero inference endpoint.&lt;/p&gt;

&lt;p&gt;**  Application owners create a namespaced LLMService describing:&lt;br&gt;
**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the model source;&lt;/li&gt;
&lt;li&gt;the desired runtime;&lt;/li&gt;
&lt;li&gt;accelerator, CPU, and memory requirements;&lt;/li&gt;
&lt;li&gt;caching and prewarming;&lt;/li&gt;
&lt;li&gt;scaling behavior; and&lt;/li&gt;
&lt;li&gt;cold-start endpoint behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;**  Cluster administrators publish reusable, cluster-scoped InferenceRuntime profiles describing:&lt;br&gt;
**&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the serving image and arguments;&lt;/li&gt;
&lt;li&gt;the device-plugin resource name;&lt;/li&gt;
&lt;li&gt;node selectors and tolerations;&lt;/li&gt;
&lt;li&gt;optional scheduler and queue configuration;&lt;/li&gt;
&lt;li&gt;health probes; and&lt;/li&gt;
&lt;li&gt;graceful termination behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation keeps serving intent portable while leaving hardware and cluster details under administrator control.&lt;/p&gt;

&lt;p&gt;From these two resources, Hearth reconciles the serving backend, a stable gateway, Kubernetes Services, model-cache resources, an optional prewarm Job, and KEDA autoscaling objects.&lt;/p&gt;

&lt;p&gt;**  Scale-to-zero that understands cold starts&lt;br&gt;
**&lt;br&gt;
  Hearth keeps a lightweight gateway available while the model backend scales between zero and the configured maximum number of replicas.&lt;/p&gt;

&lt;p&gt;The lifecycle works as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When idle, KEDA keeps the model backend at zero replicas.&lt;/li&gt;
&lt;li&gt;A request arrives at the stable Hearth gateway.&lt;/li&gt;
&lt;li&gt;The gateway records demand and either holds the request or returns 503 with Retry-After, according to policy.&lt;/li&gt;
&lt;li&gt;KEDA activates the backend through the default metrics API or the opt-in external-push scaler.&lt;/li&gt;
&lt;li&gt;The backend loads its model from cache and becomes Ready only after the serving runtime passes its health checks.&lt;/li&gt;
&lt;li&gt;The gateway forwards the request and streams the model response.&lt;/li&gt;
&lt;li&gt;Sustained queue demand can scale the backend from one replica to multiple replicas.&lt;/li&gt;
&lt;li&gt;When demand disappears, graceful draining protects in-flight streams before the backend returns to zero.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The gateway also provides bounded admission. When the queue is full, excess requests receive 429 instead of silently exhausting memory or connections. Cold-start activation has a deadline, and streaming requests can receive SSE heartbeats while waiting for the model.&lt;/p&gt;

&lt;p&gt;In v0.3.0, the new external-push mode removes KEDA’s polling interval from the initial activation path. An activation lease preserves demand even when reject mode immediately returns a 503 or when KEDA reconnects its scaler stream.&lt;/p&gt;

&lt;p&gt;The default metrics-based mode remains available for compatibility.&lt;/p&gt;

&lt;p&gt;**  Caching is part of the scale-to-zero design&lt;br&gt;
**&lt;br&gt;
  Releasing an accelerator is useful only if restarting the model remains practical.&lt;/p&gt;

&lt;p&gt;Hearth supports HostPath and NodeLocalPVC caches, optional prewarming for Hugging Face and ModelScope models, and pvc:// sources for model weights that are already staged in the cluster.&lt;/p&gt;

&lt;p&gt;Prewarm Jobs inherit the runtime’s scheduling constraints but do not request an accelerator. This lets a cluster download model weights before an inference Pod claims a GPU or NPU.&lt;/p&gt;

&lt;p&gt;Hearth also exposes stable gateway and backend metrics, while monitoring remains independent. Teams can deploy kube-prometheus-stack, another Prometheus-compatible system, or no monitoring stack at all without coupling it to the core reconciler.&lt;/p&gt;

&lt;p&gt;** Real hardware, not only rendered YAML&lt;br&gt;
**&lt;br&gt;
  Hearth’s adapters and controllers are covered by automated tests, including a CPU-only vLLM stub and complete scale-to-zero suites on Kind. But rendered manifests are not treated as proof of hardware support.&lt;/p&gt;

&lt;p&gt;The project records physical validation separately.&lt;/p&gt;

&lt;p&gt;On two NVIDIA A10 GPUs, the v0.3.0 release candidate completed the full 0→1→2→0 lifecycle using vLLM v0.25.1 and KEDA external-push. The run covered real inference, cache prewarming and persistence, bounded admission, reject mode, graceful draining, Volcano placement, component replacement, and host reboot recovery.&lt;/p&gt;

&lt;p&gt;Six pending requests drove the backend from one to two replicas, with the two Pods placed on different physical GPUs. A 105-client cold burst admitted 100 requests and rejected the remaining five with the expected 429 responses.&lt;/p&gt;

&lt;p&gt;**  Hearth and Kthena: hot models and the long tail&lt;br&gt;
**&lt;br&gt;
  Hearth does not need to replace a broader serving platform.&lt;/p&gt;

&lt;p&gt;The project includes a real-hardware demo in which Kthena keeps a frequently used model warm while Hearth manages a long-tail model on the same Kubernetes cluster. The Hearth backend starts at zero, activates when a request arrives, serves real tokens, and returns to zero afterward.&lt;/p&gt;

&lt;p&gt;This suggests a practical division of responsibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep high-traffic, latency-sensitive models on a platform designed for fleet-level serving; and&lt;/li&gt;
&lt;li&gt;place occasional or long-tail models behind Hearth’s smaller scale-to-zero lifecycle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Volcano can schedule both workloads, but it remains an external integration rather than a dependency embedded in Hearth.&lt;/p&gt;

&lt;p&gt;Watch the Hearth and Kthena operational demo (&lt;a href="https://github.com/hearth-project/hearth/blob/main/docs/demo.md" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth/blob/main/docs/demo.md&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;**  Where Hearth fits today&lt;br&gt;
**&lt;br&gt;
  Hearth v0.3.0 is alpha software with a serving.hearth.dev/v1alpha1 API.&lt;/p&gt;

&lt;p&gt;It is best suited to internal, development, laboratory, and staging environments where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;accelerator capacity is limited or expensive;&lt;/li&gt;
&lt;li&gt;some models receive intermittent traffic;&lt;/li&gt;
&lt;li&gt;cold-start latency is acceptable;&lt;/li&gt;
&lt;li&gt;workloads run inside a trusted private boundary; and&lt;/li&gt;
&lt;li&gt;teams want a small Kubernetes-native control plane rather than a complete serving platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hearth is not yet intended for shared multi-tenant clusters or public customer-facing endpoints. The gateway does not currently provide built-in authentication, and external-push mode requires one gateway replica until demand aggregation is implemented.&lt;/p&gt;

&lt;p&gt;Fractional accelerators, HAMi sharing, MIG, and general multi-node topology have not been established by the current whole-device validation.&lt;/p&gt;

&lt;p&gt;GitHub: github.com/hearth-project/hearth (&lt;a href="https://github.com/hearth-project/hearth" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth&lt;/a&gt;)&lt;br&gt;
  Release: v0.3.0 (&lt;a href="https://github.com/hearth-project/hearth/releases/tag/v0.3.0" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth/releases/tag/v0.3.0&lt;/a&gt;)&lt;br&gt;
  Roadmap: ROADMAP.md (&lt;a href="https://github.com/hearth-project/hearth/blob/main/ROADMAP.md" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth/blob/main/ROADMAP.md&lt;/a&gt;)&lt;br&gt;
  Contributing: CONTRIBUTING.md (&lt;a href="https://github.com/hearth-project/hearth/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth/blob/main/CONTRIBUTING.md&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>kubernetes</category>
      <category>llm</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Hearth: scale-to-zero LLM serving on Kubernetes — and you can hack on it without a GPU</title>
      <dc:creator>kube-gopher</dc:creator>
      <pubDate>Sun, 07 Jun 2026 12:59:16 +0000</pubDate>
      <link>https://dev.to/kubegopher/hearth-scale-to-zero-llm-serving-on-kubernetes-and-you-can-hack-on-it-without-a-gpu-bn2</link>
      <guid>https://dev.to/kubegopher/hearth-scale-to-zero-llm-serving-on-kubernetes-and-you-can-hack-on-it-without-a-gpu-bn2</guid>
      <description>&lt;p&gt;&lt;em&gt;Repo:&lt;a href="https://github.com/hearth-project/hearth" rel="noopener noreferrer"&gt;github.com/hearth-project/hearth&lt;/a&gt; · Apache-2.0 · &lt;code&gt;v0.1.0&lt;/code&gt;, alpha.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I've been building &lt;strong&gt;Hearth&lt;/strong&gt;, a Kubernetes operator that serves open-source LLMs (Qwen, DeepSeek, GLM, …) declaratively and &lt;strong&gt;scales them to zero when idle&lt;/strong&gt;. It's at a point where the core works end-to-end on real GPUs, and I'm looking for people to build it with me. The thing I most want you to know up front: &lt;strong&gt;you can contribute without owning an accelerator.&lt;/strong&gt; More on that below.&lt;/p&gt;

&lt;p&gt;## The one interesting problem&lt;/p&gt;

&lt;p&gt;Self-hosting an LLM on K8s is easy until you notice the GPU is burning money while nobody's using the model. The obvious fix — "scale to zero" — runs straight into a chicken-and-egg problem: a stock HPA can't scale &lt;em&gt;up from zero&lt;/em&gt;, because zero replicas means zero metrics, which means it never wakes up.&lt;/p&gt;

&lt;p&gt;Hearth puts a small &lt;strong&gt;gateway&lt;/strong&gt; (an OpenAI-compatible reverse proxy) in front of each model. When a request arrives at a scaled-to-zero backend, the gateway accepts it, holds the connection open (SSE keepalive heartbeats so nothing times out), and bumps a &lt;code&gt;pending&lt;/code&gt; counter exposed at &lt;code&gt;/hearth/queue&lt;/code&gt;. &lt;strong&gt;KEDA&lt;/strong&gt; polls that endpoint, sees &lt;code&gt;pending &amp;gt; 0&lt;/code&gt;, and scales the backend &lt;code&gt;0 → 1&lt;/code&gt;. The pod loads weights from a warm cache, becomes Ready, and the gateway forwards the buffered request and streams tokens back. Idle again → KEDA scales it back to &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The whole thing is one manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;serving.hearth.dev/v1alpha1&lt;/span&gt;
  &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LLMService&lt;/span&gt;
  &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;qwen3-8b&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;ai&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;uri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;modelscope&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;//Qwen/Qwen3-8B-Instruct&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;# or hf://&lt;/span&gt;
    &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;vendor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;nvidia&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ascend&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;# auto-pick a backend, in order&lt;/span&gt;
    &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;accelerators&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;1&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;scaling&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;0&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;queueDepth&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;10&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;

  &lt;span class="s"&gt;$ kubectl get llmservice -n ai&lt;/span&gt;
  &lt;span class="s"&gt;NAME       PHASE          RUNTIME       REPLICAS   AGE&lt;/span&gt;
  &lt;span class="s"&gt;qwen3-8b   ScaledToZero   vllm-nvidia   0          30s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's deliberately vendor-neutral: backends (NVIDIA-vLLM, vLLM-Ascend, …) are described as data in a cluster-scoped InferenceRuntime CRD — image, args, the device-plugin resource name, probes, metrics paths. Adding a chip is a thin adapter that does K8s-layer adaptation only; it never re-implements vLLM or touches kernels. The same LLMService is meant to run unchanged on NVIDIA or Ascend.&lt;/p&gt;

&lt;p&gt;Hearth deliberately stays in its lane: it's the K8s orchestration/lifecycle layer. The engine is vLLM; scheduling is device-plugins / HAMi / Volcano; datacenter-scale serving is KServe / llm-d Hearth is the few-GPU, scale-to-zero, private end of that spectrum.&lt;/p&gt;

&lt;p&gt;Why you can contribute without a GPU&lt;/p&gt;

&lt;p&gt;This is the part I'm proud of and the reason I'm posting. A vendor-neutral project is useless to contributors if every change needs a rack of hardware. So there's a full no-GPU test path: a CPU vllm-stub that fakes startup delay, streaming, and /metrics, plus a fake extended resource on the node. On a plain kind cluster, with no accelerator, one command —&lt;/p&gt;

&lt;p&gt;make test-scale-e2e&lt;/p&gt;

&lt;p&gt;— runs the entire 0 → 1 → N → 0 loop, including cold-start keepalive and graceful drain. A laptop is enough to develop and verify the core behavior.&lt;/p&gt;

&lt;p&gt;Honest status&lt;/p&gt;

&lt;p&gt;I won't oversell it. As of v0.1.0:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works, verified end-to-end on real NVIDIA GPUs: multi-backend abstraction, model caching/prewarm, gateway + KEDA scale-to-zero, cold-start keepalive, graceful drain, 1→N autoscaling, Helm install, Grafana dashboard.&lt;/li&gt;
&lt;li&gt;Scaffolded + golden-tested, not yet on real hardware: the Ascend backend renders correct manifests but hasn't been validated on real NPUs. This is the big v1 gap, blocked purely on hardware access.&lt;/li&gt;
&lt;li&gt;Not there yet: auth, multi-tenancy. It's v1alpha1 and not production-ready — a strong fit today for internal/dev, latency-tolerant, cost-sensitive serving.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where I'd love help&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Got Ascend (or Cambricon) hardware? Validating the Ascend backend on a real NPU is the single most valuable thing right now.&lt;/li&gt;
&lt;li&gt;No special hardware? Grab a good-first-issue (&lt;a href="https://github.com/hearth-project/hearth/issues" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth/issues&lt;/a&gt;) — the no-GPU path above means you can build, test, and verify locally.&lt;/li&gt;
&lt;li&gt;Just curious? Try the kind quickstart, poke holes, open an issue, or ⭐ and follow along.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of this resonates, the Welcome issue (#1)(&lt;a href="https://github.com/hearth-project/hearth/issues/1" rel="noopener noreferrer"&gt;https://github.com/hearth-project/hearth/issues/1&lt;/a&gt;) is the place to&lt;br&gt;
 say hi. Thanks for reading.&lt;/p&gt;

&lt;p&gt;Your models, your hearth. 🔥&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>llm</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>Idle GPUs also burn money — a Kubernetes Operator that can scale large models down to zero</title>
      <dc:creator>kube-gopher</dc:creator>
      <pubDate>Thu, 04 Jun 2026 14:30:29 +0000</pubDate>
      <link>https://dev.to/kubegopher/idle-gpus-also-burn-money-a-kubernetes-operator-that-can-scale-large-models-down-to-zero-ofa</link>
      <guid>https://dev.to/kubegopher/idle-gpus-also-burn-money-a-kubernetes-operator-that-can-scale-large-models-down-to-zero-ofa</guid>
      <description>&lt;p&gt;&lt;strong&gt;It's early — come build it with me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hearth is moving fast and contributions are very welcome — especially validating the Ascend backend on real NPUs, plus the roadmap's P0/P1 items. There are good first issues waiting.&lt;/p&gt;

&lt;p&gt;⭐ &lt;strong&gt;Star + follow along&lt;/strong&gt;: github.com/hearth-project/hearth&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your idle GPUs are burning money. Here's a Kubernetes operator that fixes it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you self-host open-source LLMs on Kubernetes, you've hit the same wall I did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A GPU pinned to a model that gets traffic 3 hours a day still costs you 24 hours a day.&lt;/li&gt;
&lt;li&gt;Every serving stack assumes NVIDIA-first, English-first — awkward if you're running Qwen, DeepSeek, or GLM, or deploying on Ascend / domestic chips.&lt;/li&gt;
&lt;li&gt;"Just use KServe" means dragging in Knative + Istio to serve one model on one GPU.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔥 Hearth — a vendor-neutral Kubernetes operator that turns "run Qwen on my private cluster" into a single LLMService manifest, with scale-to-zero built in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One manifest. Scale-to-zero. Pick your chip.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;serving.hearth.dev/v1alpha1&lt;/span&gt;
  &lt;span class="s"&gt;kind&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LLMService&lt;/span&gt;
  &lt;span class="s"&gt;metadata&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qwen3-8b&lt;/span&gt;
    &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ai&lt;/span&gt;
  &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;modelscope://Qwen/Qwen3-8B-Instruct&lt;/span&gt;
    &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;vendor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;nvidia&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ascend&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;# auto-pick a backend&lt;/span&gt;
    &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;accelerators&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="na"&gt;scaling&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;        &lt;span class="c1"&gt;# 👈 scale-to-zero&lt;/span&gt;
      &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="na"&gt;metric&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;queueDepth&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; qwen3-8b.yaml
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;kubectl get llmservice &lt;span class="nt"&gt;-n&lt;/span&gt; ai
&lt;span class="go"&gt;NAME       PHASE          RUNTIME       REPLICAS   AGE
qwen3-8b   ScaledToZero   vllm-nvidia   0          30s
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a request arrives, Hearth's gateway buffers it, scales the model 0 → 1, holds the client connection alive with SSE heartbeats through the cold start, then streams tokens back. Idle again? Back to zero GPUs.&lt;/p&gt;

&lt;p&gt;The same manifest runs on an Ascend cluster by making vllm-ascend the available runtime — no spec change. That portability is the whole point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it different&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hearth deliberately does not re-implement the things that already work:&lt;/p&gt;

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

&lt;p&gt;Backends are described declaratively in a cluster-scoped InferenceRuntime (image, args, accelerator resource, probes,metrics). Adding a new chip is a thin adapter — not a rewrite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's actually working today&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm being honest about maturity — this is pre-release v0.1.0 (alpha):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ NVIDIA backend + the full scale-to-zero path verified end-to-end on real A100s — cold-start keepalive, graceful drain (in-flight streams survive scale-down), model caching/prewarm, 1→N autoscaling, Grafana dashboard.&lt;/li&gt;
&lt;li&gt;🧪 Ascend backend is scaffolded and golden-tested (renders correct manifests) — real-NPU validation is the v1 milestone.&lt;/li&gt;
&lt;li&gt;⚠️ Not production-ready yet: no auth, no multi-tenancy. It's a strong fit today for internal / dev,latency-tolerant, cost-sensitive serving — scale-to-zero packs many idle models onto few GPUs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Try it in 60 seconds — no GPU required&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can exercise the whole control plane on kind:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;make &lt;span class="nb"&gt;install&lt;/span&gt;      &lt;span class="c"&gt;# CRDs into your kube-context&lt;/span&gt;
make run          &lt;span class="c"&gt;# run the operator&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; config/samples/serving_v1alpha1_inferenceruntime.yaml
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; config/samples/serving_v1alpha1_llmservice.yaml &lt;span class="nt"&gt;-n&lt;/span&gt; ai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ai</category>
      <category>kubernetes</category>
      <category>llm</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
