Support inference servers other than Triton, starting with Nereid - #88
Open
kondratyevd wants to merge 8 commits into
Open
Support inference servers other than Triton, starting with Nereid#88kondratyevd wants to merge 8 commits into
kondratyevd wants to merge 8 commits into
Conversation
kondratyevd
force-pushed
the
inference-server-abstraction
branch
from
September 5, 2026 15:59
9213539 to
6d29461
Compare
Preparation for supporting inference servers other than Triton: every
chart identifier that named Triton specifically is renamed to a
server-neutral one. Triton remains the default and only supported
server; this commit changes no rendered behaviour.
values key triton: -> inferenceServer:
templates templates/triton/ -> templates/inference-server/
helper supersonic.tritonName -> supersonic.inferenceServerName
resources <release>-triton -> <release>-inference-server
label component: triton -> component: inference-server
container triton-server -> inference-server
envoy cluster triton_grpc_service -> inference_server_grpc_service
triton_admission -> inference_server_admission
sidecar env GPU_DEPLOYMENT -> INFERENCE_SERVER_DEPLOYMENT
Verified by rendering the chart against all 8 values files plus chart
defaults, before and after: applying the rename map above to the
baseline reproduces the new output exactly, compared as an unordered
set of manifests (the template directory rename reorders the stream).
The rename is breaking for existing values files, so a stale top-level
`triton:` key now fails the render with a message naming the new key --
Helm would otherwise ignore it and silently deploy chart defaults. Note
that `helm lint` reports template `fail` calls as INFO, so this surfaces
on `helm install`/`helm template` rather than in the lint job.
Upgrading renames the Deployment, so Helm replaces rather than patches
it: expect a brief interruption, not an immutable-selector error.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds `inferenceServer.type` (triton | nereid) and the pieces a non-Triton server needs, without changing anything for existing Triton deployments. Nereid speaks the same KServe v2 gRPC protocol as Triton, and its bind_addr is configurable, so the rendered nereid.yaml keeps Triton's port numbers. Envoy, the Service, the ServiceMonitor, the Prometheus scrape config and the default scaling metric therefore need no per-server branching at all. What is left differing is the image, the model configuration and the probe endpoints: - Probes now accept any one of `command` (exec shorthand), `exec`, `httpGet` or `tcpSocket` instead of hardcoding exec for readiness and httpGet for startup. Nereid's image ships no curl, so it needs httpGet against the KServe v2 health endpoints. Setting two handlers is an error rather than a precedence rule. Helm merges values with the chart defaults, so adding `httpGet` does not remove the inherited `command`; picking a winner would silently probe the wrong endpoint, so switching handler must be explicit (`command: null`). - `command`/`args` are omitted when empty, so a server configured by file can use its image's entrypoint. - `inferenceServer.nereid.config` renders to a ConfigMap mounted at nereid.yaml via subPath, so it does not shadow the model folders that share Nereid's working directory. - An unknown `type` fails the render rather than producing a half-configured Deployment. yaml-to-schema.py now drops genson's inferred "required" lists. genson only ever sees values.yaml, so "required" was a copy of the defaults -- which Helm merges into every release, making the constraint unable to catch a missing key while rejecting a values file that deliberately clears one. Nulling a probe handler was blocked by exactly this. values/values-nereid.yaml is a complete worked example. Its image reference is a placeholder: nereid-server has no releases or tags yet and its GHCR package is unpublished. Verified: all 8 existing values files plus chart defaults render semantically identically to before this commit (parsed and compared as Kubernetes objects, so probe key reordering is not mistaken for change). helm lint passes on all 9 values files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A kind-based job that installs the chart with type: nereid and drives one inference through Envoy. The client is a pip-installed tritonclient rather than the one in the Triton SDK image: the claim under test is that an unmodified KServe v2 client works against Nereid, and building it from Triton's own proto stubs is what makes that a cross-implementation check rather than a self-consistency one. Tensor names and shapes come from ModelMetadata instead of being hardcoded, so the metadata path is covered too. perf_analyzer is not used -- it needs the model-config and statistics RPCs, which Nereid does not implement. The model is nereid-server's own ml-backends/model3 example (a 10 KB TorchScript MLP) vendored into a ConfigMap, so the job needs no model volume, no CVMFS and no network fetch. It is served by the Rust torch backend, which is in the image's default feature set and needs no writable model directory -- unlike the Python backend, which builds a venv/ inside each model folder. Mounting it required a `configMap` modelRepository storageType, which also gives small models and test deployments a first-class option. mountPropagation is omitted for it, since the API server rejects that field on a configMap volume. The job is gated on the Nereid image actually being published: the repository has no tags yet and its GHCR package is unpublished, so the gate skips with a GitHub notice rather than failing for a reason unrelated to this chart. Remove the gate once a release exists. Verified: all 8 existing values files plus chart defaults still render semantically identically; helm lint passes on all 11 values files. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a "Select an Inference Server" section to the configuration guide comparing the two types, with a worked Nereid snippet and the two Triton-only caveats: Nereid exports no nv_gpu_* metrics (so the GPU dashboard panels and metricsCollector do not apply), and its Python backend needs a writable model folder, so a read-only volume serves only .pt/ONNX/TensorFlow models. The rest of the guide keeps saying "Triton" only where it really means Triton -- image selection, the model repository layout, the tritonserver command line. Everywhere the chart is now server-agnostic the wording follows. Also documents the new configMap model repository option, and fixes the section numbering, which had two sections numbered 1. Dashboard panels retitled from "Number of Triton Servers"; the queries are untouched, verified by diffing the rendered dashboard ConfigMap. helm/supersonic/README.md is the CI-maintained copy of the root README, refreshed here so the tree is self-consistent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Chart.yaml no longer declares an opentelemetry-collector dependency after #87, so `helm dependency build` has nothing to resolve from that repository. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#86 replaced `kubectl wait --for=condition=complete` with scripts/wait-for-job.sh, which polls for Complete OR Failed so a failed Job reports immediately instead of idling until the timeout, and extracted failure dumps into the k8s-diagnostics composite action. This job was written against the older conventions and was the only one left hand-rolling both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
kondratyevd
force-pushed
the
inference-server-abstraction
branch
from
September 5, 2026 20:56
6d29461 to
ae2f4bb
Compare
ngpaladi/nereid-server#20 implements the RepositoryIndex RPC that scaleFromZero triggers on, so it is no longer an assumption with nothing behind it. Its proto is the same vendored `inference.GRPCInferenceService`, so the path Envoy routes and the Lua filter matches is identical for both server types; the chart needs no change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Prometheus Operator install floats on whatever prometheus-community/kube-prometheus-stack is latest. 90.0.0, published between 2026-09-05 and 2026-09-07, made the control-plane ServiceMonitors authenticate via a Secret that is only rendered when prometheus.enabled and prometheus.serviceAccount.create are both true. These call sites pass prometheus.enabled=false -- they want the operator and its CRDs, nothing else -- so templating now fails: The control-plane ServiceMonitors authenticate by default with the Secret created by prometheus.serviceAccount.createTokenSecret, which is only rendered when prometheus.enabled and prometheus.serviceAccount.create are also true. Bisected: 89.2.4 and every earlier release template fine with these flags; 90.0.0 is the first that does not. Pinning 89.2.4 keeps CI reproducible and matches how the chart's own dependencies are pinned. 89.2.4 still ships the servicemonitors CRD and the operator Deployment, which is all these steps need. The alternative -- tracking latest and disabling every control-plane exporter (kubelet, kubeApiServer, kubeControllerManager, kubeScheduler, kubeProxy, kubeEtcd, coreDns) -- also works on 90.0.0 but adds seven flags to each call site and would not protect against the next upstream change. This break is independent of this branch: it fails identically on main, which has not run CI since 90.0.0 was published. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extends SuperSONIC to run inference servers other than Triton, and adds
Nereid as the second supported type.
Nereid speaks the same KServe v2 gRPC protocol as Triton, and its
bind_addrisconfigurable, so the rendered
nereid.yamlkeeps Triton's port numbers. Envoy, theService, the ServiceMonitor, the Prometheus scrape config and the default scaling
metric therefore need no per-server branching. What genuinely differs is the
image, the model configuration and the probe endpoints.
Commits
ec1cf9e8a6709fc7cc61c9213539Breaking change:
triton:→inferenceServer:triton:inferenceServer:templates/triton/templates/inference-server/supersonic.tritonNamesupersonic.inferenceServerName<release>-triton<release>-inference-servercomponent: tritoncomponent: inference-servertriton_grpc_service,triton_admissioninference_server_*GPU_DEPLOYMENTINFERENCE_SERVER_DEPLOYMENTEvery downstream values file needs its top-level
triton:key renamed. A stalekey now fails the render with a message naming the replacement — Helm would otherwise
ignore it and silently deploy chart defaults. Note that
helm lintreports templatefailcalls as INFO, so this surfaces onhelm install/helm template, not in thelint job.
Upgrading renames the Deployment, so Helm replaces rather than patches it: expect a
brief interruption, not an immutable-selector error.
What's new
inferenceServer.type(triton|nereid); an unknown value fails the render.Probes accept any one of
command(exec shorthand),exec,httpGetortcpSocket. Nereid's image ships nocurl, so it needshttpGetagainst theKServe v2 health endpoints.
Setting two handlers is an error rather than a precedence rule. Helm merges values
with the chart defaults, so adding
httpGetdoes not remove the inheritedcommand; picking a winner would silently probe the wrong endpoint. Switchinghandler is explicit:
command: null.command/argsare omitted when empty, so a file-configured server uses itsimage's entrypoint.
inferenceServer.nereid.configrenders to a ConfigMap mounted atnereid.yamlvia
subPath, so it does not shadow the model folders sharing Nereid's workingdirectory.
A
configMapmodel-repositorystorageType, for small models and testing.values/values-nereid.yaml— a complete worked example.Testing
.github/workflows/ci-nereid.yamlinstalls the chart withtype: nereidon kind anddrives one inference through Envoy.
The client is a pip-installed
tritonclientrather than the one in the Triton SDKimage: the claim under test is that an unmodified KServe v2 client works against
Nereid, and building it from Triton's own proto stubs is what makes that a
cross-implementation check rather than a self-consistency one. Tensor names and shapes
come from
ModelMetadatainstead of being hardcoded.perf_analyzeris deliberatelynot used — it needs the model-config and statistics RPCs, which Nereid does not
implement.
The model is nereid-server's own
ml-backends/model3example (a 10 KB TorchScriptMLP) vendored into a ConfigMap, so the job needs no model volume, no CVMFS and no
network fetch.
Verification of the rename
All 8 pre-existing values files plus chart defaults were rendered before and after
every commit and compared as parsed Kubernetes objects, so key reordering is not
mistaken for change. The only intended render difference in the whole PR is the
dashboard panel retitling, confirmed by diffing the rendered dashboard ConfigMap to be
titles only, no query changes.
helm lintpasses on all 11 values files.Upstream dependencies — please read before merging
/v2/health/{live,ready}endpointsthe probes use and the Triton-named
nv_inference_*metrics that the ServiceMonitorscrapes and the default
serverLoadMetricreads. Until it merges, Nereid has noworking probe endpoint and no scaling metric.
RepositoryIndexRPC thatscaleFromZerotriggers on. Nothing in that path is Triton-specific: Nereid vendorsthe same
inference.GRPCInferenceServiceproto, so/inference.GRPCInferenceService/RepositoryIndex— the path the Envoy route and theLua filter match on — is identical for both server types, and the chart needs no
change. Until it merges,
scaleFromZerocannot be used withtype: nereid.its GHCR package is unpublished, so the CI job is gated on the image resolving and
skips with a GitHub notice until then. Remove the gate and pin a tag once a release
exists.
Not addressed, documented as Triton-only
Nereid exports no
nv_gpu_*metrics (explicitly out of scope of #19), so the GPUpanels of the Grafana dashboard and the optional
metricsCollectorstay blank underNereid. Reworking the dashboard belongs in its own PR.
Incidental fixes
yaml-to-schema.pynow drops genson's inferredrequiredlists. genson only eversees
values.yaml, sorequiredwas a copy of the defaults — which Helm merges intoevery release, making the constraint unable to catch a missing key while rejecting a
values file that deliberately clears one. Nulling a probe handler was blocked by
exactly this. This is a repo-wide change beyond the Nereid work.
1..Known sharp edge, not fixed
The same generator types
inferenceServer.resources.requests.cpuasintegerfrom thesingle sample in
values.yaml, socpu: 500m— or evencpu: 0.5— is rejected there.Worked around with
cpu: 1in the CI values rather than widening this PR's scope.Rebased onto #87 and #86
Rebased onto
mainafter both merged. Resolutions, in each case taking the upstreamcontent and applying this branch's rename to it:
From #87 (OpenTelemetry/Tempo removal):
values.yaml— theenvoy.tracing_sampling_rateknob I had reworded is gone withtracing support; took the deletion.
dashboards/with-server-map.json— deleted upstream, so my panel retitling in it wentaway with the file.
dashboards/default.jsonstill carries the retitling.From #86 (dependency upgrades):
bumps, the Envoy
admin.access_log/typed_extension_protocol_optionsmigrations,and the FQDN form of the upstream address in the external-config test.
the
triton_admissioncalls in its new KEDA-hold refresh path,.tritonNamein theEnvoy cluster address, and
supersonic-triton.cms.svc.cluster.local.in the testfixture, plus its new user-facing strings (
reject_reason, comments).scripts/wait-for-job.sh(pollsfor Complete or Failed, so a failed Job reports immediately instead of idling to
the timeout) and the
k8s-diagnosticscomposite action. This job was the only oneleft hand-rolling both.
values.schema.jsonanddocs/.values-table.mdare generated, so they were regeneratedat each step using the generator version in effect at that commit, rather than
hand-merged.
Re-verified against the current
main: all 8 pre-existing values files plus chartdefaults render identically once the rename map is applied, compared field by field as
parsed Kubernetes objects. The only differences are this branch's own wording changes —
confirmed by diffing the rendered Lua, Envoy and dashboard blobs to be comments, log
strings and panel titles, with no logic or query changes.
helm lintpasses on all 10values files, both guard-rails fire, and the Envoy cluster names the Lua filter calls
all resolve against the generated config.
🤖 Generated with Claude Code