Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Support Guide
url: https://github.com/waqasm86/llm-observability-stack/blob/main/SUPPORT.md
url: https://github.com/Edge-Computing-LLM/llm-observability-stack/blob/main/SUPPORT.md
about: Check support and troubleshooting guidance before opening an issue.
19 changes: 6 additions & 13 deletions .github/workflows/helm-validate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ on:
push:
pull_request:

permissions:
contents: read

jobs:
lint-and-render:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Set up Helm
uses: azure/setup-helm@v4
uses: azure/setup-helm@v5
with:
version: v3.15.4

Expand Down Expand Up @@ -39,18 +42,8 @@ jobs:
--set open-webui.webuiSecret.existingSecretName= \
>/tmp/rendered-full-stack-nvidia.yaml

- name: Build and validate monitoring chart
run: |
if [ ! -d monitoring ]; then
echo "monitoring chart is not present in this repository; skipping optional monitoring chart validation"
exit 0
fi
helm dependency build monitoring
helm lint monitoring
helm template llm-monitoring monitoring >/tmp/rendered-monitoring.yaml

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.11"

Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ values.local-*.yaml
*.key
*.crt
*.kubeconfig
kubeconfig
kubeconfig*

# Generated render/debug artifacts
.generated/
Expand Down Expand Up @@ -43,6 +45,9 @@ pictures/
charts/*.tgz
charts/**/*.tgz
monitoring/charts/*.tgz
llm-observability-stack-*.tgz
*.tar.gz
*.zip
# Large model/data artifacts (keep out of git)
*.gguf
*.safetensors
Expand Down Expand Up @@ -84,6 +89,7 @@ rendered-with-etcd.yaml
*.private.yaml
jupyter-notebooks/python*-pip-list.txt
local-run-output/
validation-output/
*.kube-report.json
*.kubeconfig.bak
evidence-local-run/
3 changes: 3 additions & 0 deletions .helmignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ python-toolbox/examples/service_dns_check.py

# Vendored chart docs/assets are not needed at install time
charts/*.tgz
charts/gpu-operator/
charts/nvidia-device-plugin/
charts/dcgm-exporter/
charts/ollama/README.md
charts/ollama/LICENSE
charts/ollama/artifacthub-repo.yml
Expand Down
13 changes: 2 additions & 11 deletions Chart.lock
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
dependencies:
- name: gpu-operator
repository: file://charts/gpu-operator
version: v1.0.0-devel
- name: nvidia-device-plugin
repository: file://charts/nvidia-device-plugin
version: 0.19.2
- name: dcgm-exporter
repository: file://charts/dcgm-exporter
version: 4.8.2
- name: ollama
repository: file://charts/ollama
version: 1.50.0
Expand All @@ -23,5 +14,5 @@ dependencies:
- name: opentelemetry-operator
repository: file://charts/opentelemetry-operator
version: 0.115.0
digest: sha256:7a8de8212f1051cbddc881e9d7d865424f83be907ccd7d5da91491038579eba5
generated: "2026-06-16T14:22:44.167855506+05:00"
digest: sha256:9a3e5dc71273d49fd4f3e8a46e8142ca5c83ffb8163c9666c97f4a558af01480
generated: "2026-07-08T19:18:56.195921069+05:00"
15 changes: 0 additions & 15 deletions Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ kubeVersion: ">=1.27.0-0"
home: https://github.com/Edge-Computing-LLM/llm-observability-stack
sources:
- https://github.com/prometheus-community/helm-charts
- https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/
- https://github.com/NVIDIA/k8s-device-plugin
- https://github.com/NVIDIA/dcgm-exporter
- https://github.com/open-telemetry/opentelemetry-helm-charts
- https://github.com/otwld/ollama-helm
- https://github.com/open-webui/helm-charts
Expand All @@ -37,18 +34,6 @@ keywords:
- opentelemetry
- genai
dependencies:
- name: gpu-operator
version: v1.0.0-devel
repository: file://charts/gpu-operator
condition: gpu-operator.enabled
- name: nvidia-device-plugin
version: 0.19.2
repository: file://charts/nvidia-device-plugin
condition: nvidia-device-plugin.enabled
- name: dcgm-exporter
version: 4.8.2
repository: file://charts/dcgm-exporter
condition: dcgm-exporter.enabled
- name: ollama
version: 1.50.0
repository: file://charts/ollama
Expand Down
27 changes: 27 additions & 0 deletions Modelfile.qwen-1.8b-chat-q4_K_M
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Modelfile for the locally retained Ollama Qwen 1.8B Chat Q4_K_M GGUF.
#
# Upstream: https://ollama.com/library/qwen:1.8b-chat-q4_K_M
# GGUF SHA-256: ef0125bcc77278420b64229fc29e235435c517f67ab7aa8546a9f5f7be644cef
# License: Tongyi Qianwen Research License (non-commercial use unless separately licensed).
#
# The GeForce 940M has 1 GiB VRAM. Live tuning on this host showed that 24 GPU
# layers use 860 MiB, while 23 GPU layers use 824 MiB. Keep num_batch at 1:
# larger batches make this Qwen architecture reserve a CUDA graph buffer that
# does not fit on this GPU.

FROM /models/gguf/qwen-1.8b-chat-q4_K_M.gguf

TEMPLATE """<|im_start|>system
{{ .System }}<|im_end|>
<|im_start|>user
{{ .Prompt }}<|im_end|>
<|im_start|>assistant
"""

PARAMETER stop "<|im_start|>"
PARAMETER stop "<|im_end|>"
PARAMETER num_gpu 23
PARAMETER num_ctx 256
PARAMETER num_batch 1
PARAMETER num_predict 128
PARAMETER temperature 0
84 changes: 60 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

Kubernetes-native observability, benchmarking, and operations tooling for private LLM inference on local edge systems.

Go CLI documentation: [docs/cli.md](docs/cli.md).
Preferred organization CLI: [`edge-cli`](https://github.com/Edge-Computing-LLM/edge-cli).
Repo-local legacy/helper CLI documentation: [docs/cli.md](docs/cli.md).

This repository packages a Helm-based stack for k3s and Kubernetes with Ollama/GGUF model serving, Open WebUI, an OpenTelemetry GenAI-instrumented FastAPI proxy, Prometheus, Grafana, OpenTelemetry Collector, blackbox probes, benchmark metrics, and optional NVIDIA GPU monitoring through the NVIDIA runtime, device plugin, GPU Operator, and DCGM-compatible dashboards.
This repository packages a Helm-based application and observability stack for k3s and Kubernetes with Ollama/GGUF model serving, Open WebUI, an OpenTelemetry GenAI-instrumented FastAPI proxy, Prometheus, Grafana, OpenTelemetry Collector, blackbox probes, benchmark metrics, and NVIDIA/DCGM-compatible dashboards.

The repository also includes a Go CLI named `llm-observability`. It reuses `github.com/Edge-Computing-LLM/k3s-nvidia-edge/pkg/edgebase` for base-layer checks and keeps application-specific Helm, validation, and benchmark workflows in this repository.
The repository also includes a Go CLI named `llm-observability` for repo-local helper workflows. New end-to-end installs should use `edge-cli`, which deploys `k3s-nvidia-edge` first and then this chart.

GitHub repository: <https://github.com/Edge-Computing-LLM/llm-observability-stack>

Expand All @@ -16,6 +17,8 @@ For local NVIDIA GPU deployments, deploy [`k3s-nvidia-edge`](https://github.com/

`k3s-nvidia-edge` owns k3s, k3s containerd NVIDIA runtime wiring, GPU Operator, NVIDIA device plugin, DCGM exporter, Node Feature Discovery, `RuntimeClass/nvidia`, and the allocatable `nvidia.com/gpu` resource. `llm-observability-stack` then deploys Ollama, Open WebUI, OpenTelemetry, dashboards, benchmarks, and application-level observability on top of that base layer.

An empty local k3s cluster with only CoreDNS, local-path-provisioner, and other default k3s system components is a valid starting point before the base layer is deployed. Run `edge install infra` or validate `k3s-nvidia-edge` before installing GPU profiles from this repository.

Read the full dependency guide before installing GPU profiles:

- [k3s-nvidia-edge dependency](docs/K3S-NVIDIA-EDGE-DEPENDENCY.md)
Expand All @@ -25,7 +28,7 @@ Read the full dependency guide before installing GPU profiles:
- Local private LLM serving through Ollama and legally obtained GGUF models.
- Kubernetes deployment through Helm with k3s-friendly profiles.
- NVIDIA GPU scheduling with `runtimeClassName: nvidia` and `nvidia.com/gpu` when a GPU is available.
- CPU-only deployment profiles for MacOS/minikube and k3s systems without NVIDIA GPUs.
- Optional CPU validation profiles for development clusters without NVIDIA GPUs.
- Open WebUI for browser-based interaction with local models.
- A FastAPI proxy with LLM request metrics for TTFT, latency, tokens per second, prompt tokens, generated tokens, active requests, and errors.
- Prometheus, Grafana, Alertmanager, kube-state-metrics, node exporter, ServiceMonitors, probes, and alert rules.
Expand All @@ -41,30 +44,44 @@ The current local deployment target is a single-node Xubuntu 24 system running k
- k3s node: combined control-plane and worker.
- NVIDIA device plugin resource: `nvidia.com/gpu: 1`.
- RuntimeClass: `nvidia`.
- Model: Gemma 3 1B IT Q4_K_M GGUF.
- Model: Qwen 1.8B Chat Q4_K_M GGUF through the local alias
`qwen-1-8b-chat-q4-k-m-local`.

Measured after one warmup and three streaming benchmark requests:
Measured after deployment, warmup, and exact-response, arithmetic, and
translation inference checks:

| Metric | Result |
|---|---:|
| TTFT p50 | 0.377 s |
| TTFT p95 | 0.381 s |
| Mean throughput | 11.69 tokens/s |
| End-to-end p95 | 6.97 s |
| Peak GPU utilization | 52% |
| VRAM usage | 554 MiB |
| Model size | Approximately 1.2 GB |
| CUDA layers | 23/25 |
| Processor split | 27% CPU / 73% GPU |
| Context / batch | 256 / 1 |
| Observed throughput | 9.75-15.78 tokens/s |
| VRAM usage | 824 MiB used / 152 MiB free |
| Residency | `Forever` |

Evidence and reproduction:

- [Single-node k3s GeForce 940M guide](docs/SINGLE-NODE-K3S-GEFORCE-940M.md)
- [Local k3s NVIDIA deployment report - 2026-07-02](docs/LOCAL-K3S-NVIDIA-REPORT-2026-07-02.md)
- [Live layered validation - 2026-07-08](docs/LIVE-VALIDATION-2026-07-08.md)
- [Verified local GPU results](docs/VERIFIED-LOCAL-GPU-RESULTS.md)
- [Xubuntu k3s NVIDIA runbook](docs/XUBUNTU-K3S-NVIDIA-RUNBOOK.md)
- [Sanitized benchmark artifact](artifacts/geforce-940m-benchmark.json)
- [GeForce 940M Helm profile](values.geforce-940m-k3s.yaml)
- [Qwen GGUF runtime evidence companion](https://github.com/Edge-Computing-LLM/qwen-gguf-observability)

These numbers prove constrained local edge feasibility. They do not claim enterprise load, concurrency, fleet reliability, or production readiness.

The companion repository performs read-only runtime contract checks and
captures sanitized evidence. This chart remains the source of truth for the
Modelfile, Helm values, model lifecycle, and workload configuration.

The separate
[`Frontend-Edge-LLM-Observability`](https://github.com/Edge-Computing-LLM/Frontend-Edge-LLM-Observability)
project provides the TypeScript/Vue dashboard. It consumes controlled DCGM and
future telemetry endpoints; frontend source is not duplicated in this chart.

## Who This Is For

- Developers running private LLMs on local Linux systems.
Expand All @@ -82,7 +99,7 @@ These numbers prove constrained local edge feasibility. They do not claim enterp

## Platform Components

- Vendored Helm charts for Ollama, Open WebUI, NVIDIA GPU Operator, NVIDIA device plugin, DCGM exporter, kube-prometheus-stack, OpenTelemetry Collector, and OpenTelemetry Operator.
- Vendored Helm charts for Ollama, Open WebUI, kube-prometheus-stack, OpenTelemetry Collector, and OpenTelemetry Operator.
- FastAPI OpenTelemetry GenAI-instrumented proxy with Prometheus metrics.
- TTFT, latency, token, throughput, active-request, HTTP, and error telemetry.
- Optional kube-prometheus-stack, Grafana, Alertmanager, node exporter, and kube-state-metrics from the root umbrella chart.
Expand Down Expand Up @@ -115,7 +132,7 @@ Prometheus + Grafana + Alertmanager
+-- ServiceMonitors, probes, benchmark Pushgateway, Kubernetes metrics
```

The verified laptop profile uses Ollama/GGUF. The same observability contract can be used on larger RTX workstations, GPU Operator/DCGM clusters, NIM endpoints, or cloud GPU clusters.
The verified laptop profile uses Ollama/GGUF. The same observability contract can be used on larger local RTX workstations with the NVIDIA substrate prepared by `k3s-nvidia-edge`.

## Repository Layout

Expand Down Expand Up @@ -149,7 +166,14 @@ Build the CLI:
go build -o bin/llm-observability ./cmd/llm-observability
```

Recommended local CLI flow when `k3s-nvidia-edge` is already healthy:
Preferred local CLI flow from the organization control plane:

```bash
edge install all --accelerator auto --yes
edge validate observability
```

Repo-local helper flow when `k3s-nvidia-edge` is already healthy:

```bash
bin/llm-observability doctor
Expand All @@ -163,7 +187,7 @@ bin/llm-observability validate
- Helm 3 or 4.
- For local NVIDIA k3s GPU profiles: `k3s-nvidia-edge` deployed and validated first.
- NVIDIA driver and NVIDIA Container Toolkit for GPU profiles.
- NVIDIA device plugin or GPU Operator exposing `nvidia.com/gpu` for GPU mode.
- `RuntimeClass/nvidia` and `nvidia.com/gpu` provided by `k3s-nvidia-edge` for GPU mode.
- A legally obtained GGUF model available on node storage.
- Python 3.11 for tests and benchmark tooling.

Expand All @@ -180,6 +204,11 @@ helm version

The local bootstrap helper detects the Kubernetes runtime before installing. It uses NVIDIA mode when Kubernetes advertises `nvidia.com/gpu`; otherwise it writes a CPU-only overlay and runs the same edge LLM observability path without NVIDIA runtime or GPU resource requests.

The organization CLI exposes the same policy directly. The full installer uses
host detection, while `edge install observability --accelerator auto --yes` uses
Kubernetes allocatable GPU capacity. Explicit `cpu` and `nvidia` modes are also
available for deterministic automation.

## Quick Start

### A. Minimal validation profile
Expand All @@ -193,18 +222,22 @@ helm template llm-observability-stack . \

Review the machine-specific model host path before using this profile on another system. The profile schedules on nodes with `nvidia.com/gpu.present=true`, which supports a single-node k3s control-plane/worker laptop without requiring a separate worker label.

Deploy and validate `k3s-nvidia-edge` first:
This profile uses the locally retained Qwen 1.8B Chat Q4_K_M GGUF and
`Modelfile.qwen-1.8b-chat-q4_K_M`. On the 1 GiB GeForce 940M it pins 23/25
layers to CUDA, limits batch size to 1, uses a 256-token context, and keeps the
model loaded indefinitely. The measured steady-state allocation is 824 MiB VRAM.

Preferred: deploy and validate the base layer through `edge-cli` first:

```bash
cd /media/waqasm86/External1/Waqas-Projects/Project-Edge-Computing-LLM/k3s-nvidia-edge
bin/k3s-nvidia-edge install --yes --sudo=false --use-local-chart --skip-base-package-install --skip-toolkit-install --skip-k3s-install
bin/k3s-nvidia-edge validate --yes
edge install infra --yes
edge validate infra
```

Then deploy the LLM stack:

```bash
cd /media/waqasm86/External1/Waqas-Projects/Project-Edge-Computing-LLM/llm-observability-stack
cd /media/waqasm86/External1/Waqas-Projects/Project-Linux-Kubernetes-Nvidia/Project-Edge-Computing-LLM/llm-observability-stack

helm upgrade --install llm-observability-stack . \
-n llm-observability --create-namespace \
Expand All @@ -213,15 +246,18 @@ helm upgrade --install llm-observability-stack . \
./hack/test-geforce-940m-inference.sh
```

### C. Full-stack NVIDIA profile
### C. Full observability NVIDIA profile

```bash
helm upgrade --install llm-observability-stack . \
-n llm-observability --create-namespace \
-f values.full-stack-nvidia.example.yaml
```

Use private values files or existing Kubernetes Secrets for OpenTelemetry and Open WebUI secrets. Never commit secrets.
This installs the LLM and observability layer only. It does not install GPU
Operator, NVIDIA device plugin, or DCGM exporter. Use private values files or
existing Kubernetes Secrets for OpenTelemetry and Open WebUI secrets. Never
commit secrets.

### D. Local full-stack k3s profile

Expand Down Expand Up @@ -272,7 +308,7 @@ Run the public benchmark from another terminal:

```bash
./benchmarks/ollama_benchmark.py \
--model gemma3-1b-it-gguf-local \
--model qwen-1-8b-chat-q4-k-m-local \
--warmup-runs 1 \
--runs 10 \
--output artifacts/benchmark-local.json
Expand Down
4 changes: 2 additions & 2 deletions SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

Use GitHub Issues for setup, debugging, and enhancement questions:

- Repository: https://github.com/waqasm86/llm-observability-stack
- New issue: https://github.com/waqasm86/llm-observability-stack/issues/new
- Repository: https://github.com/Edge-Computing-LLM/llm-observability-stack
- New issue: https://github.com/Edge-Computing-LLM/llm-observability-stack/issues/new

## What to Include

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/ollama_benchmark.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python3.11
"""Run repeatable Ollama streaming benchmarks and optionally publish summary metrics."""

from __future__ import annotations
Expand Down
Loading