piqc 1.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. piqc-1.2.0/LICENSE +25 -0
  2. piqc-1.2.0/PKG-INFO +618 -0
  3. piqc-1.2.0/README.md +583 -0
  4. piqc-1.2.0/pyproject.toml +130 -0
  5. piqc-1.2.0/src/piqc/__init__.py +10 -0
  6. piqc-1.2.0/src/piqc/__main__.py +11 -0
  7. piqc-1.2.0/src/piqc/cli/__init__.py +1 -0
  8. piqc-1.2.0/src/piqc/cli/commands.py +566 -0
  9. piqc-1.2.0/src/piqc/collectors/__init__.py +1 -0
  10. piqc-1.2.0/src/piqc/collectors/amd/__init__.py +14 -0
  11. piqc-1.2.0/src/piqc/collectors/config_collector.py +238 -0
  12. piqc-1.2.0/src/piqc/collectors/gpu_collector.py +313 -0
  13. piqc-1.2.0/src/piqc/collectors/vllm_api_client.py +674 -0
  14. piqc-1.2.0/src/piqc/collectors/vllm_collector.py +328 -0
  15. piqc-1.2.0/src/piqc/core/__init__.py +1 -0
  16. piqc-1.2.0/src/piqc/core/aggregator.py +302 -0
  17. piqc-1.2.0/src/piqc/core/confidence.py +225 -0
  18. piqc-1.2.0/src/piqc/core/discovery.py +563 -0
  19. piqc-1.2.0/src/piqc/core/k8s_client.py +604 -0
  20. piqc-1.2.0/src/piqc/core/llm_d/__init__.py +16 -0
  21. piqc-1.2.0/src/piqc/core/modes.py +153 -0
  22. piqc-1.2.0/src/piqc/core/orchestrator.py +829 -0
  23. piqc-1.2.0/src/piqc/generators/__init__.py +1 -0
  24. piqc-1.2.0/src/piqc/generators/json_generator.py +139 -0
  25. piqc-1.2.0/src/piqc/generators/piqc_generator.py +1010 -0
  26. piqc-1.2.0/src/piqc/generators/table_generator.py +797 -0
  27. piqc-1.2.0/src/piqc/generators/yaml_generator.py +183 -0
  28. piqc-1.2.0/src/piqc/models/__init__.py +31 -0
  29. piqc-1.2.0/src/piqc/models/modelspec.py +419 -0
  30. piqc-1.2.0/src/piqc/models/piqc_schema.py +246 -0
  31. piqc-1.2.0/src/piqc/parsers/__init__.py +1 -0
  32. piqc-1.2.0/src/piqc/parsers/vllm_parser.py +227 -0
  33. piqc-1.2.0/src/piqc/telemetry.py +156 -0
  34. piqc-1.2.0/src/piqc/utils/__init__.py +1 -0
  35. piqc-1.2.0/src/piqc/utils/exceptions.py +223 -0
  36. piqc-1.2.0/src/piqc/utils/logger.py +183 -0
piqc-1.2.0/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Business Source License 1.1
2
+
3
+ Licensor: ParallelIQ LLC
4
+ Licensed Work: ModelSpec
5
+ Change Date: January 1, 2028
6
+ Change License: Apache 2.0
7
+ Additional Use Grant: None
8
+
9
+ Terms:
10
+
11
+ The Licensor hereby grants you the right to copy, modify, create derivative works, redistribute, and make non-production use of the Licensed Work. The Licensor may make an Additional Use Grant, above, permitting limited production use.
12
+
13
+ Effective on the Change Date, or the fourth anniversary of the first publicly available distribution of a specific version of the Licensed Work under this License, whichever comes first, the Licensor hereby grants you rights under the terms of the Change License stated above, and the rights granted in the paragraph above terminate.
14
+
15
+ If your use of the Licensed Work does not comply with the requirements currently in effect as described in this License, you must purchase a commercial license from the Licensor, its affiliated entities, or authorized resellers, or you must refrain from using the Licensed Work.
16
+
17
+ All copies of the original and modified Licensed Work, and derivative works of the Licensed Work, are subject to this License. This License applies separately for each version of the Licensed Work and the Change Date may vary for each version of the Licensed Work released by the Licensor.
18
+
19
+ You must conspicuously display this License on each original or modified copy of the Licensed Work. If you receive the Licensed Work in original or modified form from a third party, the terms and conditions set forth in this License apply to your use of that work.
20
+
21
+ Any use of the Licensed Work in violation of this License will automatically terminate your rights under this License for the current and all other versions of the Licensed Work.
22
+
23
+ This License does not grant you any right in any trademark or logo of the Licensor or its affiliates (except as may be necessary to comply with the requirements of this License).
24
+
25
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE.
piqc-1.2.0/PKG-INFO ADDED
@@ -0,0 +1,618 @@
1
+ Metadata-Version: 2.4
2
+ Name: piqc
3
+ Version: 1.2.0
4
+ Summary: Open-source vLLM-native fact collector for AI/ML inference fleets on Kubernetes — detects GPU waste, idle capacity, and tier misplacement
5
+ License: Apache-2.0
6
+ License-File: LICENSE
7
+ Keywords: kubernetes,ml,ai,vllm,inference,modelspec
8
+ Author: ParallelIQ Cloud
9
+ Author-email: engineering@paralleliq.ai
10
+ Requires-Python: >=3.11,<4.0
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Classifier: Topic :: Utilities
24
+ Requires-Dist: click (>=8.1.7,<9.0.0)
25
+ Requires-Dist: kubernetes (>=30.1.0,<31.0.0)
26
+ Requires-Dist: pydantic (>=2.5.0,<3.0.0)
27
+ Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
28
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
29
+ Requires-Dist: rich (>=13.7.0,<14.0.0)
30
+ Project-URL: Documentation, https://github.com/paralleliq/piqc#readme
31
+ Project-URL: Homepage, https://paralleliq.ai
32
+ Project-URL: Repository, https://github.com/paralleliq/piqc
33
+ Description-Content-Type: text/markdown
34
+
35
+ <p align="center">
36
+ <img src="https://img.shields.io/badge/PIQC-v1.0.0-blue?style=for-the-badge&logo=kubernetes&logoColor=white" alt="PIQC Version"/>
37
+ <img src="https://img.shields.io/badge/Python-3.11+-green?style=for-the-badge&logo=python&logoColor=white" alt="Python"/>
38
+ <img src="https://img.shields.io/badge/License-Apache%202.0-orange?style=for-the-badge" alt="License"/>
39
+ <img src="https://img.shields.io/badge/vLLM-Supported-purple?style=for-the-badge" alt="vLLM"/>
40
+ <img src="https://img.shields.io/badge/Ray%20Serve-Supported-blue?style=for-the-badge" alt="Ray Serve"/>
41
+ <img src="https://img.shields.io/github/stars/paralleliq/piqc?style=for-the-badge&logo=github&color=yellow" alt="GitHub Stars"/>
42
+ </p>
43
+
44
+ <h1 align="center">piqc — Inference Fact Collector for AI Infrastructure Optimization</h1>
45
+
46
+ <p align="center">
47
+ <strong>Most AI clusters waste 20–40% of GPU spend. piqc finds it in one command.</strong>
48
+ <br/><br/>
49
+ vLLM-native · Hardware-pluggable · Read-only · No agents · No sidecars · Nothing installed permanently
50
+ </p>
51
+
52
+ <p align="center">
53
+ <a href="#-quick-start">Quick Start</a> •
54
+ <a href="#-features">Features</a> •
55
+ <a href="#-orchestrator-integrations">Integrations</a> •
56
+ <a href="#-commands">Commands</a> •
57
+ <a href="#-output-formats">Output Formats</a> •
58
+ <a href="#-installation">Installation</a>
59
+ </p>
60
+
61
+ ---
62
+
63
+ ## What is piqc?
64
+
65
+ piqc is an open-source inference fact collector for Kubernetes clusters. It collects model-aware facts — what is running, on what hardware, at what cost, with what waste — and surfaces them as a standardized facts bundle that feeds an optimization layer. It also prints a human-readable cost report so you can act on the results immediately without any external platform.
66
+
67
+ It is the fastest way to answer: **how much GPU spend is my Kubernetes cluster wasting right now?**
68
+
69
+ ```
70
+ piqc
71
+ └── inference collector (vLLM-native) ← collects model, GPU, KV cache, throughput facts
72
+ └── hardware collector (plugin) ← vendors contribute their own telemetry
73
+ ├── nvidia/ (DCGM, MIG state)
74
+ ├── amd/ (ROCm metrics)
75
+ └── your-hardware/
76
+ ```
77
+
78
+ Facts flow to the [Paralleliq optimization layer](https://paralleliq.ai), which maps waste to the model level and routes remediations through human-approved workflows. piqc runs standalone too — no platform required to get value from the cost report.
79
+
80
+ piqc surfaces three types of waste that standard Kubernetes monitoring (`kubectl top`, `kube-state-metrics`, Prometheus node exporters) cannot detect on their own:
81
+ - **Idle allocation** — pods holding GPU resources with near-zero compute utilization
82
+ - **Tier misplacement** — models running on GPU tiers with far more memory or compute than they need
83
+ - **Dark capacity** — GPU nodes with no pods scheduled at all
84
+
85
+ It works with any Kubernetes cluster running GPU inference workloads — GKE, EKS, AKS, on-prem, or bare metal. vLLM is the primary supported inference framework, with Ray Serve workloads also detected (GPU type, utilization, and cost — deeper runtime metrics like KV cache and token throughput are vLLM-specific). Hardware fact collection is pluggable — see [Contributing a Hardware Plugin](#contributing-a-hardware-plugin).
86
+
87
+ ---
88
+
89
+ ## What you'll see
90
+
91
+ Run `piqc scan` against your cluster and get an instant cost report:
92
+
93
+ ```
94
+ Discovered Inference Deployments
95
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━┳━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┓
96
+ ┃ Deployment ┃ Engine ┃ GPU ┃ Replicas ┃ Age ┃ GPU Util ┃ MFU ┃ $/1K tokens ┃ $/hr ┃ Idle $/day ┃
97
+ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━╇━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━┩
98
+ │ meta-llama/Llama-3-70B-Inst │ vllm │ 8xH100-SXM4-80GB ⚠ │ 2 │ 6h │ 4% │ 3.1% │ $0.0842 │ $68.00 │ $1,566.72 │
99
+ │ mistral-7b-instruct │ vllm │ 1xA100-SXM4-40GB ⚠ │ 1 │ 2d │ 11% │ 8.4% │ $0.0073 │ $2.50 │ $53.40 │
100
+ │ codellama-34b-staging │ vllm │ 4xH100-SXM4-80GB ⚠ │ 1 │ 19d │ 0% │ N/A │ N/A │ $17.00 │ $408.00 │
101
+ │ embedding-bge-large │ vllm │ 1xT4 ✓ │ 3 │ 14h │ 82% │ N/A │ $0.0002 │ $1.35 │ $5.83 │
102
+ │ unknown-runtime-7f3a2 │ unknown │ 2xA100-SXM4-80GB ? │ 1 │ 31d │ N/A │ N/A │ N/A │ $7.00 │ util unknown │
103
+ └─────────────────────────────┴─────────┴────────────────────┴──────────┴─────┴──────────┴──────┴─────────────┴────────┴──────────────┘
104
+
105
+ ⚠ tier larger than this model requires · ? model size unknown — fit not checked · Age running 3+ days — confirm it's still needed
106
+
107
+ ╭──────────────────────────────────── Cost Summary ──────────────────────────────────────╮
108
+ │ Total GPU spend rate : $95.85/hr │
109
+ │ │
110
+ │ Leased & idle (util <60%) : $2,033.95/day (low utilization — may reflect traffic │
111
+ │ patterns; worth investigating) │
112
+ │ Unallocated nodes : $1,152.00/day (12 GPU(s) with no pods scheduled) │
113
+ │ Tier misplacement : $721.20/day (3 model(s) on oversized GPU tier) │
114
+ │ │
115
+ │ Total estimated leak : $3,907.15/day ($1,426,110/yr at current rate) │
116
+ │ │
117
+ │ Confirmed waste : unallocated nodes, tier misplacement │
118
+ │ Signals to investigate: low GPU utilization (verify against traffic data) │
119
+ │ │
120
+ │ Avg MFU (active deployments) : 15.7% (healthy range: 30–60%) │
121
+ ╰────────────────────────────────────────────────────────────────────────────────────────╯
122
+ ─────────────────────────────────────────────────────────────
123
+ → Want to know what this waste is actually costing you?
124
+ Paralleliq turns these signals into confirmed findings with dollar impact,
125
+ continuous monitoring, and automated remediation — so you act on facts, not guesses.
126
+ Running proprietary models or on-prem hardware? We'll configure it for your exact costs.
127
+ Free to get started: paralleliq.ai · Questions? sam@paralleliq.ai
128
+ ```
129
+
130
+ **piqc is free and open source.** The scan gives you the full picture — what is running, on what hardware, at what cost, and where the waste is. For continuous monitoring, alerting across your fleet, and automated remediation workflows, see [paralleliq.ai](https://paralleliq.ai).
131
+
132
+ ---
133
+
134
+ ## 🚀 Quick Start
135
+
136
+ ### Option 1: Run as a Kubernetes Job (recommended)
137
+
138
+ Runs inside your cluster — no Docker auth or kubeconfig wrangling:
139
+
140
+ ```bash
141
+ # Step 1 — Apply RBAC permissions (one-time setup)
142
+ kubectl apply -f https://raw.githubusercontent.com/paralleliq/piqc/main/deploy/rbac.yaml
143
+
144
+ # Step 2 — Run the scan
145
+ kubectl apply -f https://raw.githubusercontent.com/paralleliq/piqc/main/deploy/scan-job.yaml
146
+
147
+ # Step 3 — View the output
148
+ kubectl logs -f job/piqc-scan -n kube-system
149
+
150
+ # Clean up when done
151
+ kubectl delete job piqc-scan -n kube-system
152
+ ```
153
+
154
+ > The job auto-deletes itself after 10 minutes (`ttlSecondsAfterFinished: 600`).
155
+
156
+ ---
157
+
158
+ ### Option 2: Run with Docker from your laptop
159
+
160
+ ```bash
161
+ # Export a static kubeconfig with embedded credentials
162
+ kubectl config view --raw --flatten > /tmp/piqc-kubeconfig.yaml
163
+
164
+ # Run the scan
165
+ docker run --rm \
166
+ -v /tmp/piqc-kubeconfig.yaml:/root/.kube/config \
167
+ ghcr.io/paralleliq/piqc:latest \
168
+ scan --format table
169
+ ```
170
+
171
+ Supports both `linux/amd64` and `linux/arm64`.
172
+
173
+ ---
174
+
175
+ ### Option 3: Install from source
176
+
177
+ ```bash
178
+ git clone https://github.com/paralleliq/piqc.git
179
+ cd piqc
180
+ poetry install
181
+ poetry run piqc scan --format table
182
+ ```
183
+
184
+ ---
185
+
186
+ ## ✨ Features
187
+
188
+ ### 🔍 Intelligent Discovery
189
+ - **Auto-Detection**: Automatically discovers vLLM and Ray Serve inference deployments across all namespaces
190
+ - **Weighted Confidence Scoring**: Uses multiple signals (images, env vars, CLI args, labels) with weighted scoring
191
+ - **Framework Detection**: Identifies vLLM and Ray Serve with high accuracy using pattern matching and heuristics
192
+
193
+ ### 📊 Comprehensive Metrics Collection
194
+ - **GPU Metrics**: Real-time GPU utilization, memory, temperature, and power via `nvidia-smi`
195
+ - **Runtime Metrics**: Collects vLLM API metrics including:
196
+ - Request latency (P50, P95, P99)
197
+ - Token throughput (prefill & decode)
198
+ - KV cache utilization
199
+ - Queue depth and active requests
200
+ - Health status
201
+
202
+ ### 💰 Waste Detection
203
+ - **GPU underutilization** — Deployments below 60% utilization threshold, with dollar waste per day and annualized
204
+ - **Dark capacity** — GPU nodes with no pods scheduled (paying for nodes sitting empty)
205
+ - **Tier misplacement** — Models running on an oversized GPU tier, with estimated cost delta per day
206
+ - **Fragmentation** — Nodes with free GPU slots too small to fit any running model
207
+ - **Pending GPU pods** — Workloads blocked from scheduling, shown with wait time
208
+ - **Cost Summary panel** — Total spend rate, all waste categories, total estimated leak per day and per year
209
+ - **MFU (Model FLOPS Utilization)** — Observed compute vs. theoretical GPU peak per deployment
210
+ - **Cost per 1K tokens** — GPU spend translated into a business metric comparable to API pricing
211
+
212
+ ### 📄 Multiple Output Formats
213
+ | Format | Description |
214
+ |--------|-------------|
215
+ | **Table** | Cost report with MFU, $/1K tokens, idle waste (default) |
216
+ | **YAML** | Kubernetes-style inference deployment files |
217
+ | **JSON** | Machine-readable JSON output |
218
+ | **PIQC Facts** | Standardized facts bundle for control plane integration |
219
+
220
+ ### 🚀 Production-Ready
221
+ - **Parallel Processing**: Multi-threaded scanning with configurable workers
222
+ - **RBAC Support**: Pre-configured ClusterRole and ServiceAccount manifests
223
+ - **Flexible Modes**: Auto-detect, remote (kubeconfig), or in-cluster execution
224
+ - **Timeout Controls**: Configurable operation timeouts
225
+ - **Docker Image**: Pre-built multi-platform image (`linux/amd64` + `linux/arm64`) on GitHub Container Registry
226
+
227
+ ### 🔌 Hardware Plugins
228
+
229
+ piqc's hardware fact collection is designed to be pluggable. The inference collector (vLLM) is maintained in this repo. Hardware vendors contribute their own collectors using the same fact schema — so AMD, Intel, and custom hardware telemetry can be added without touching the core.
230
+
231
+ <table>
232
+ <tr>
233
+ <td width="50%" valign="top">
234
+
235
+ **🔴 AMD GPU Plugin**
236
+
237
+ Hardware plugin for AMD Instinct GPUs via `rocm-smi`:
238
+ - AMD Instinct MI250X/MI300X detection
239
+ - GPU utilization, memory & temperature metrics
240
+ - ROCm ecosystem integration
241
+ - Contributed by the community / AMD
242
+
243
+ </td>
244
+ <td width="50%" valign="top">
245
+
246
+ **🌐 LLM-D (LLM-Distributed)**
247
+
248
+ Discovery and documentation for distributed LLM inference:
249
+ - Distributed inference topology mapping
250
+ - Multi-node GPU coordination metrics
251
+ - Cross-node performance aggregation
252
+ - Distributed KV cache analysis
253
+
254
+ </td>
255
+ </tr>
256
+ </table>
257
+
258
+ Want to contribute a hardware plugin? See [Contributing a Hardware Plugin](#contributing-a-hardware-plugin).
259
+
260
+ ---
261
+
262
+ ## 🔌 Orchestrator Integrations
263
+
264
+ ### dstack
265
+
266
+ [`paralleliq-dstack-plugin`](https://github.com/paralleliq/paralleliq-dstack-plugin) ([PyPI](https://pypi.org/project/paralleliq-dstack-plugin/)) hooks into [dstack](https://dstack.ai)'s plugin system. When a GPU fleet or task is applied against a dstack project on a Kubernetes backend, it surfaces the piqc scan commands so you know to check for waste on the cluster dstack just provisioned onto.
267
+
268
+ ```bash
269
+ pip install paralleliq-dstack-plugin
270
+ ```
271
+
272
+ dstack discovers it automatically via Python entry points — no further configuration required. See the plugin repo for what it does today and its current limitations.
273
+
274
+ ---
275
+
276
+ ## 📋 Commands
277
+
278
+ ### `piqc scan`
279
+
280
+ **Scan your Kubernetes cluster for inference workloads and surface GPU waste.**
281
+
282
+ ```bash
283
+ piqc scan [OPTIONS]
284
+ ```
285
+
286
+ #### Scan Options
287
+
288
+ | Option | Default | Description |
289
+ |--------|---------|-------------|
290
+ | `--kubeconfig PATH` | `~/.kube/config` | Path to kubeconfig file |
291
+ | `--context TEXT` | current | Kubernetes context to use |
292
+ | `-n, --namespace TEXT` | all | Specific namespace to scan |
293
+ | `--format [yaml\|json\|table]` | `yaml` | Output format |
294
+ | `-o, --output PATH` | `./output` | Output directory for generated files |
295
+
296
+ #### Collection Options
297
+
298
+ | Option | Default | Description |
299
+ |--------|---------|-------------|
300
+ | `--collect-runtime` | `false` | Collect runtime metrics via vLLM API |
301
+ | `--no-exec` | `false` | Disable pod exec (skip GPU metrics) |
302
+ | `--no-logs` | `false` | Disable log reading |
303
+ | `--aggregate/--no-aggregate` | `aggregate` | Aggregate metrics across pod replicas |
304
+ | `--contribute-benchmarks` | `false` | Contribute anonymized GPU/model performance data to the Paralleliq benchmark dataset |
305
+
306
+ #### Output Options
307
+
308
+ | Option | Default | Description |
309
+ |--------|---------|-------------|
310
+ | `--combined` | `false` | Generate single combined output file |
311
+ | `--output-piqc` | `false` | Generate `piqc-facts.json` (PIQC v0.1 schema) |
312
+
313
+ #### Execution Options
314
+
315
+ | Option | Default | Description |
316
+ |--------|---------|-------------|
317
+ | `--timeout INT` | `30` | Operation timeout in seconds |
318
+ | `--workers INT` | `10` | Number of parallel workers |
319
+ | `--mode [auto\|remote\|incluster\|dry-run]` | `auto` | Execution mode |
320
+ | `-v, --verbose` | `false` | Enable verbose output |
321
+ | `--debug` | `false` | Enable debug mode with detailed trace |
322
+
323
+ #### Examples
324
+
325
+ ```bash
326
+ # Basic scan — discover all vLLM deployments and surface waste
327
+ piqc scan
328
+
329
+ # Scan specific namespace with JSON output
330
+ piqc scan -n production --format json
331
+
332
+ # Quick scan without GPU metrics (faster)
333
+ piqc scan --no-exec
334
+
335
+ # Collect runtime metrics from vLLM API
336
+ piqc scan --collect-runtime
337
+
338
+ # Generate PIQC facts bundle for control plane integration
339
+ piqc scan --output-piqc -o ./facts
340
+
341
+ # Table output to console (human-readable)
342
+ piqc scan --format table
343
+
344
+ # Custom kubeconfig and context
345
+ piqc scan --kubeconfig /path/to/config --context my-cluster
346
+
347
+ # Contribute anonymized GPU/model benchmarks to Paralleliq dataset
348
+ piqc scan --contribute-benchmarks
349
+ ```
350
+
351
+ ---
352
+
353
+ ### `piqc test-connection`
354
+
355
+ **Test connection to Kubernetes cluster and verify required permissions.**
356
+
357
+ ```bash
358
+ piqc test-connection [OPTIONS]
359
+ ```
360
+
361
+ | Option | Default | Description |
362
+ |--------|---------|-------------|
363
+ | `--kubeconfig PATH` | `~/.kube/config` | Path to kubeconfig file |
364
+ | `--context TEXT` | current | Kubernetes context to use |
365
+
366
+ ---
367
+
368
+ ### `piqc version`
369
+
370
+ ```bash
371
+ piqc version
372
+ ```
373
+
374
+ ---
375
+
376
+ ## 📁 Output Formats
377
+
378
+ ### Table Format (default)
379
+
380
+ Run `piqc scan --format table` — no flags required. See the [output example](#what-youll-see) above.
381
+
382
+ **GPU column markers** (tier fit, shown inline next to the GPU type):
383
+ | Symbol | Meaning |
384
+ |--------|---------|
385
+ | `✓` | Model is on an appropriate GPU tier for its size |
386
+ | `⚠` | Model is over-provisioned for an oversized GPU tier |
387
+ | `?` | Parameter count not parseable from model name — fit not checked |
388
+
389
+ **Age column:** shown as `5m` / `2h` / `19d` since the deployment's pods were created. Deployments running 3+ days are highlighted — long-running GPU allocations are easy to forget about and keep billing unnoticed.
390
+
391
+ ### YAML Format
392
+
393
+ Generates individual Kubernetes-style YAML files for each deployment:
394
+
395
+ ```yaml
396
+ apiVersion: piqc/v1
397
+ kind: InferenceDeployment
398
+ metadata:
399
+ name: vllm-llama-7b
400
+ namespace: inference
401
+ collectionTimestamp: "2024-01-07T12:00:00Z"
402
+ collectorVersion: "1.0.0"
403
+ model:
404
+ name: meta-llama/Llama-2-7b-hf
405
+ architecture: llama
406
+ parameters: "7B"
407
+ identificationConfidence: 0.95
408
+ engine:
409
+ name: vllm
410
+ version: "0.4.0"
411
+ detectionConfidence: 0.95
412
+ inference:
413
+ precision: float16
414
+ tensorParallelSize: 4
415
+ maxModelLen: 4096
416
+ gpuMemoryUtilization: 0.90
417
+ resources:
418
+ replicas: 2
419
+ gpuCount: 4
420
+ gpus:
421
+ - type: A100-SXM4-80GB
422
+ memoryTotal: "80GB"
423
+ utilization: 87
424
+ memoryUsed: 72000
425
+ runtimeState:
426
+ vllm:
427
+ healthStatus: healthy
428
+ kvCacheUsagePercent: 45.2
429
+ avgPromptThroughput: 1250.5
430
+ avgGenerationThroughput: 85.3
431
+ ```
432
+
433
+ ### PIQC Facts Bundle
434
+
435
+ With `--output-piqc`, generates a standardized facts bundle for integration with the [Paralleliq optimization layer](https://paralleliq.ai):
436
+
437
+ ```json
438
+ {
439
+ "schemaVersion": "piqc-scan.v0.1",
440
+ "generatedAt": "2026-06-20T12:00:00Z",
441
+ "tool": {
442
+ "name": "piqc",
443
+ "version": "1.1.0"
444
+ },
445
+ "cluster": {
446
+ "context": "my-context",
447
+ "name": "my-cluster"
448
+ },
449
+ "objects": [
450
+ {
451
+ "workloadId": "ns/inference/deployment/vllm-llama-7b",
452
+ "kind": "Deployment",
453
+ "name": "vllm-llama-7b",
454
+ "namespace": "inference",
455
+ "facts": {
456
+ "runtime.engineType": {"value": "vllm", "dataConfidence": "high"},
457
+ "hardware.gpuType": {"value": "A100-SXM4-80GB", "dataConfidence": "high"},
458
+ "hardware.gpuCount": {"value": 4, "dataConfidence": "high"},
459
+ "obs.gpu.memUtilAvgPct": {"value": 87, "dataConfidence": "high"},
460
+ "obs.vllm.kvCacheUsagePct": {"value": 45.2, "dataConfidence": "high", "units": "%"},
461
+ "obs.vllm.requestsRunning": {"value": 3, "dataConfidence": "high"},
462
+ "obs.vllm.requestsWaiting": {"value": 0, "dataConfidence": "high"},
463
+ "k8s.ageHours": {"value": 18.5, "dataConfidence": "high", "units": "hours"}
464
+ }
465
+ },
466
+ {
467
+ "workloadId": "ns/gpu-pool/node/h100-node-07",
468
+ "kind": "Node",
469
+ "name": "h100-node-07",
470
+ "namespace": "gpu-pool",
471
+ "facts": {
472
+ "hardware.gpuType": {"value": "nvidia-h100-80gb", "dataConfidence": "high"},
473
+ "hardware.gpuCount": {"value": 4, "dataConfidence": "high"},
474
+ "node.allocatedGpuCount": {"value": 2, "dataConfidence": "high"},
475
+ "node.unallocatedGpuCount": {"value": 2, "dataConfidence": "high"}
476
+ }
477
+ }
478
+ ]
479
+ }
480
+ ```
481
+
482
+ The first object is a normal scanned workload. The second is a node-scoped object — emitted when a node has GPU capacity no pod has requested (the "Dark capacity" case under Waste Detection above); it carries no `runtime.*`/`model.*` facts since it isn't describing a running inference workload.
483
+
484
+ ---
485
+
486
+ ## 📥 Installation
487
+
488
+ ### Prerequisites
489
+
490
+ - **Python**: 3.11 or higher
491
+ - **Kubernetes Access**: Valid kubeconfig with cluster access
492
+ - **Poetry**: For development installation
493
+
494
+ ### Install from Source
495
+
496
+ ```bash
497
+ git clone https://github.com/paralleliq/piqc.git
498
+ cd piqc
499
+ poetry install
500
+ poetry run piqc --version
501
+ ```
502
+
503
+ ### Install for Development
504
+
505
+ ```bash
506
+ git clone https://github.com/paralleliq/piqc.git
507
+ cd piqc
508
+ poetry install --with dev
509
+ poetry run pytest tests/unit -v
510
+ ```
511
+
512
+ ---
513
+
514
+ ## 🔐 Kubernetes RBAC Requirements
515
+
516
+ piqc is **read-only**. It never creates, modifies, or deletes any resource in your cluster. The only write permission is `pods/exec` (to run `nvidia-smi` inside pods for GPU metrics) — and that can be disabled with `--no-exec`.
517
+
518
+ ```bash
519
+ kubectl apply -f https://raw.githubusercontent.com/paralleliq/piqc/main/deploy/rbac.yaml
520
+ ```
521
+
522
+ | Resource | Verbs | Purpose |
523
+ |----------|-------|---------|
524
+ | `pods` | get, list | Discover inference workloads |
525
+ | `pods/exec` | create | Run nvidia-smi for GPU metrics |
526
+ | `pods/log` | get | Enhanced framework detection |
527
+ | `namespaces` | get, list | Scan multiple namespaces |
528
+ | `deployments` | get, list | Identify deployment metadata |
529
+ | `statefulsets` | get, list | Identify StatefulSet workloads |
530
+ | `services` | get, list | Endpoint detection |
531
+
532
+ ---
533
+
534
+ ## 🔧 Execution Modes
535
+
536
+ | Mode | Description |
537
+ |------|-------------|
538
+ | `auto` | Automatically detect if running in-cluster or remotely |
539
+ | `remote` | Force remote mode (uses kubeconfig) |
540
+ | `incluster` | Force in-cluster mode (uses ServiceAccount) |
541
+ | `dry-run` | Simulate scan without cluster access |
542
+
543
+ ---
544
+
545
+ ## 🐛 Troubleshooting
546
+
547
+ ### Docker Auth Plugin Errors (GKE / EKS / AKS)
548
+
549
+ Use the in-cluster Job approach (Option 1 in Quick Start) — it runs inside the cluster and needs no auth plugins. Or export a static kubeconfig:
550
+
551
+ ```bash
552
+ kubectl config view --raw --flatten > /tmp/piqc-kubeconfig.yaml
553
+ docker run --rm -v /tmp/piqc-kubeconfig.yaml:/root/.kube/config ghcr.io/paralleliq/piqc:latest scan
554
+ ```
555
+
556
+ ### RBAC Permission Errors
557
+
558
+ ```bash
559
+ kubectl auth can-i list pods --all-namespaces
560
+ kubectl auth can-i create pods/exec -n <namespace>
561
+ kubectl apply -f https://raw.githubusercontent.com/paralleliq/piqc/main/deploy/rbac.yaml
562
+ ```
563
+
564
+ ### GPU Metrics Unavailable
565
+
566
+ ```bash
567
+ piqc scan --no-exec
568
+ ```
569
+
570
+ ---
571
+
572
+ ## 📚 Project Structure
573
+
574
+ ```
575
+ piqc/
576
+ ├── src/piqc/
577
+ │ ├── cli/ # CLI commands (scan, test-connection, version)
578
+ │ ├── collectors/ # Data collectors (vLLM config, GPU metrics)
579
+ │ ├── core/ # Core logic (orchestrator, discovery, k8s client)
580
+ │ ├── generators/ # Output generators (YAML, JSON, Table, PIQC)
581
+ │ ├── models/ # Pydantic data models (inference deployment, PIQC schema)
582
+ │ ├── parsers/ # Configuration parsers (vLLM)
583
+ │ └── utils/ # Utilities (logging, exceptions)
584
+ ├── tests/
585
+ │ ├── unit/ # Unit tests
586
+ │ └── integration/ # Integration tests
587
+ ├── rbac/ # Kubernetes RBAC manifests
588
+ ├── docs/ # Documentation
589
+ └── examples/ # Example scan outputs and facts bundles
590
+ ```
591
+
592
+ ---
593
+
594
+ ## What to do with the results
595
+
596
+ piqc tells you what's wrong. The [Paralleliq optimization layer](https://paralleliq.ai) closes the loop — it ingests the piqc facts bundle, maps waste to the model level, and routes remediations through human-approved workflows with a full audit trail.
597
+
598
+ → [paralleliq.ai](https://paralleliq.ai) · [info@paralleliq.ai](mailto:info@paralleliq.ai)
599
+
600
+ ---
601
+
602
+ ## Contributing a Hardware Plugin
603
+
604
+ piqc's hardware fact collection is designed so hardware vendors and community contributors can add support for their own GPU or accelerator without modifying the core inference collector.
605
+
606
+ A hardware plugin is a collector that:
607
+ 1. Reads telemetry from the target hardware (via `nvidia-smi`, `rocm-smi`, vendor BMC API, or equivalent)
608
+ 2. Emits facts using the piqc fact schema (`hardware.gpuType`, `hardware.gpuCount`, `observed.gpuUtilization`, etc.)
609
+ 3. Lives under `src/piqc/collectors/hardware/<vendor>/`
610
+
611
+ The vLLM inference collector is the reference implementation. If you represent a hardware vendor or want to contribute support for AMD, Intel Gaudi, or another accelerator, open an issue or email [info@paralleliq.ai](mailto:info@paralleliq.ai).
612
+
613
+ ---
614
+
615
+ ## 📄 License
616
+
617
+ Apache License 2.0 — see [LICENSE](LICENSE) for details.
618
+