Skip to main content

paygo-ptu-cost-analyzer

Headless Azure OpenAI PAYGO-vs-PTU cost analysis and sizing report. Wraps the analysis library of aiappsgbb/ptu-paygo-mix (NOT its Streamlit UI). Supports CSV token-usage input and Log Analytics queries via vendored KQL against `AzureMetrics`. Produces a markdown report, JSON data, and charts. Bundles a synthetic-data generator for offline demos. USE FOR: ptu sizing, paygo vs ptu, provisioned throughput unit recommendation, AOAI capacity planning, TPM percentile report, spillover cost estimate, log analytics token query, AzureMetrics PTU, CSV-based PTU sizing, headless cost report, paygo-ptu-cost-analyzer. DO NOT USE FOR: capacity reservation purchase workflow, deploying the upstream Streamlit UI (use the upstream repo), real-time TPM monitoring (use azure-monitor-query directly), pricing for non-Azure-OpenAI services.

Zur Installation springen

Quellinformationen

Repository
aiappsgbb/awesome-gbb
Letzte Quellaktivität
16. September 2026 um 10:12
Erkannte Sprache von SKILL.md
Englisch
Sterne
6
Forks
3

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
12 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
paygo-ptu-cost-analyzer
description
Headless Azure OpenAI PAYGO-vs-PTU cost analysis and sizing report. Wraps the analysis library of aiappsgbb/ptu-paygo-mix (NOT its Streamlit UI). Supports CSV token-usage input and Log Analytics queries via vendored KQL against `AzureMetrics`. Produces a markdown report, JSON data, and charts. Bundles a synthetic-data generator for offline demos. USE FOR: ptu sizing, paygo vs ptu, provisioned throughput unit recommendation, AOAI capacity planning, TPM percentile report, spillover cost estimate, log analytics token query, AzureMetrics PTU, CSV-based PTU sizing, headless cost report, paygo-ptu-cost-analyzer. DO NOT USE FOR: capacity reservation purchase workflow, deploying the upstream Streamlit UI (use the upstream repo), real-time TPM monitoring (use azure-monitor-query directly), pricing for non-Azure-OpenAI services.
metadata
{"version":"1.1.1"}
# PAYGO vs PTU Cost Analyzer Headless cost-analysis skill for **Azure OpenAI**. Given a window of per-minute token usage, it computes the percentile TPM envelope, prices both **PAYGO** and **PTU** scenarios per percentile, estimates spillover costs, and emits a markdown + JSON + PNG report. This is the analysis core of **aiappsgbb/ptu-paygo-mix** wrapped in a CLI; the upstream Streamlit UI is **excluded by design** (this skill runs in a terminal, in CI, or inside an agent — never as a web app). > **Sister capability.** If you actually want the interactive UI, use > the upstream repo directly (`uv run streamlit run app/streamlit_app.py`). > This skill is for the cases where the seller / analyst / agent needs > a **report file** — over chat, in a PR, or as part of an automated > capacity-planning rollup. > **Continuous monitoring companion.** [`foundry-cost-monitoring`](../foundry-cost-monitoring/SKILL.md) > consumes live OTel `gen_ai.usage.*` spans for per-agent / per-project > cost projection — use it when the FinOps question is "what's my > spend right now?" rather than "how should I size PTU?" --- ## Two data paths | Path | When to use | Auth needed | |------|-------------|-------------| | `--csv <path>` | Customer already exported their token usage (e.g. via the upstream `docs/sample_kql_queries.md`, Excel, Cost Mgmt export). | None. | | `--workspace <id>` | You have direct read access on the Log Analytics workspace ingesting Cognitive Services metrics. | `DefaultAzureCredential` (az login / managed identity / env vars / VS Code) with `Log Analytics Reader` on the workspace. | | `--synthetic` | Offline demo, regression test, or you need to show the report shape before real data lands. | None. | All three paths converge on the same `run_analysis()` and `render_report()` so the output contract is identical. ### Required CSV schema | Column | Type | Notes | |--------|------|-------| | `minute_bin` | datetime (parseable) | Per-minute bucket. | | `input_tokens_sum` | int | Total input tokens in the bucket (includes cached). | | `cached_tokens_sum` | int | Subset of `input_tokens_sum` that hit the prompt cache. | | `output_tokens_sum` | int | Generated tokens. | `normalize_usage_dataframe()` validates the schema, parses datetimes, strips thousands separators, and sorts by `minute_bin`. Bad input fails loudly with a descriptive `ValueError`. --- ## Quickstart ```bash # 0. One-time deps (matches references/upstream-pin.md) python3 -m venv .venv && source .venv/bin/activate pip install "pandas~=3.0.3" "numpy~=2.4.6" "matplotlib~=3.11.0" \ "azure-identity~=1.25.3" "azure-monitor-query~=2.0.0" # 1. Offline demo — uses the bundled synthetic generator python references/run_report.py \ --synthetic --days 3 \ --model gpt-5.4 --tier global --ptu-term monthly \ --out-dir ./paygo-ptu-report # 2. Customer CSV python references/run_report.py \ --csv ./customer_tpm_april.csv \ --model gpt-5.2 --tier data_zone --ptu-term yearly \ --percentiles 75,90,95,99 \ --out-dir ./customer-report # 3. Live Log Analytics (requires az login + workspace Reader role) python references/run_report.py \ --workspace 11111111-2222-3333-4444-555555555555 \ --time-range 14d \ --deployment my-gpt-5-4-prod \ --model gpt-5.4 \ --out-dir ./live-report # A bundled tiny CSV is also available for smoke tests: python references/run_report.py \ --csv references/sample_input.csv --model gpt-5.4 --out-dir /tmp/smoke ``` Every run prints the 4 absolute output paths to stdout and exits 0 on success, non-zero on validation errors. --- ## Output contract Every run produces exactly these four files under `--out-dir`: | File | Contents | |------|----------| | `report.md` | Narrative report: input window summary, percentile TPM table, PAYGO baseline breakdown, per-percentile PTU sizing scenarios (PTUs, capacity, covered-token %, base cost, spillover cost, total, ∆ vs PAYGO), recommendation paragraph, pricing snapshot. | | `report.json` | Full `run_analysis()` dict + run metadata (`model`, `tier`, `ptu_term`, `source`, `percentiles`, `pricing_snapshot`, `generated_at`). Reconsumable by downstream agents. | | `tpm_over_time.png` | Line chart of `total_tpm` over `minute_bin` with horizontal dashed lines for each percentile's PTU capacity (so you can eyeball spillover). | | `ptu_sizing_scenarios.png` | Grouped bar chart per percentile: PTU base cost (blue) stacked with spillover cost (orange), plus a green dashed line at the PAYGO baseline. Each bar labelled with the total. | The markdown report always contains the substrings `"PTU Sizing"`, `"PAYGO Baseline"`, and `"p95"` (the freshness validator asserts these). --- ## CLI reference (`run_report.py`) | Flag | Default | Notes | |------|---------|-------| | `--csv <path>` | — | CSV matching the required schema. Mutually exclusive with `--workspace` / `--synthetic`. | | `--workspace <id>` | — | Log Analytics workspace GUID. Mutually exclusive. | | `--synthetic` | — | Use the bundled synthetic generator. Mutually exclusive. | | `--kql <path>` | `references/queries/default.kql` | KQL template; placeholders `__TIME_RANGE__`, `__DEPLOYMENT_FILTER__`. | | `--time-range` | `7d` | `Nd` or `Nh`. Applied to KQL + Log Analytics timespan. | | `--deployment` | _empty_ | Filter to a specific Cognitive Services deployment. Optional. | | `--days` | `7` | Synthetic data duration. | | `--model` | `gpt-5.4` | Slug from `references/analyzer/models.json`. | | `--tier` | `global` | `global` or `data_zone` (per the catalog). | | `--ptu-term` | `monthly` | `monthly` or `yearly`. Switches the cost columns + recommendation. | | `--percentiles` | `50,75,90,95,99` | Comma-separated, in `(0,100)`. | | `--ptu-output-weight` | model's `ptu.output_weight` | Multiplier on output-token TPM when sizing PTUs. Defaults to the selected model's catalog `ptu.output_weight` (e.g. `6` for gpt-5.4); pass a value to override (e.g. `1.0` for the old flat behaviour). Falls back to `1` if the model has no `output_weight`. | | `--out-dir` | `./paygo-ptu-report` | Created if absent. | --- ## Pricing catalog (`references/analyzer/models.json`) Vendored from the upstream repo. Each model entry carries: - `paygo.global` + optional `paygo.data_zone` → `input_per_m`, `cached_input_per_m`, `output_per_m`, plus optional `priority_processing` rates - `ptu.capacity_tpm`, `ptu.min_deployment`, `ptu.increment`, `ptu.output_weight` - `ptu.global` + optional `ptu.data_zone` → `monthly_price`, `yearly_price` `ptu.output_weight` (typically 4–8) scales output-token TPM when sizing PTUs; `--ptu-output-weight` defaults to it (see the CLI table). As of the `2636464` re-vendor the catalog also ships **gpt-5.5** and **gpt-5.4-mini**, and **gpt-5.4** now carries `data_zone` pricing (so `--tier data_zone` resolves for it). To use a custom catalog: edit `models.json` in place (it's a vendored file — not auto-refreshed). The upstream-pin tracks the SHA of the upstream repo so the catalog can be re-vendored when prices drift. > **Pricing drift is real.** Microsoft updates Azure OpenAI pricing > several times a year. Treat the bundled `models.json` as a **starting > point** for a customer conversation, not a quote — always confirm > against the current pricing page for the customer's region and the > region of their reservation. --- ## Vendored layout ``` references/ ├── analyzer/ # Analysis core vendored from aiappsgbb/ptu-paygo-mix @ 2636464 │ ├── __init__.py # Re-exports the public API │ ├── analysis.py # run_analysis() — pure pandas/numpy │ ├── data.py # load/normalize/KQL helpers (frozen @ e1786f8, Streamlit stripped) │ ├── formatting.py # fmt_num / fmt_cost │ └── models.json # PTU + PAYGO pricing catalog ├── queries/ │ ├── default.kql # AzureMetrics → required schema (InputTokens path) │ └── active_tokens.kql # Alternative: derives cached from ActiveTokens ├── render_report.py # md + json + 2× png (matplotlib, Agg backend) ├── run_report.py # CLI entry point ├── sample_input.csv # ~10 KB demo CSV (240 rows, reproducible seed) └── upstream-pin.md # Tier-B freshness contract ``` `analysis.py`, `formatting.py`, and `models.json` are byte-identical to upstream `@ 2636464`. Three files **intentionally diverge**: - `data.py` — **frozen at the `e1786f8` shape** (Streamlit stripped: the `import streamlit as st` line and both `@st.cache_data` / `@st.cache_data(ttl=300)` decorators removed). Upstream **deleted** its live Log-Analytics / KQL path at commit `14a5bec`; this skill keeps it to power `--workspace` mode, so `data.py` is **not** re-vendored from newer SHAs. See `upstream-pin.md` KI-002. - `queries/*.kql` — **retained**; upstream deleted the `kql/` directory at `14a5bec`. These drive the `--workspace` path. - `__init__.py` — exported names match the `e1786f8` upstream plus `REQUIRED_COLUMNS`, `MODELS_CONFIG_PATH`, `time_range_to_timedelta`. Re-vendoring the analysis core is a manual chore signalled by SHA drift in `upstream-pin.md` (the upstream repo is private — a token with read access is needed to clone it). --- ## KQL path notes The bundled query targets `AzureMetrics` for the Cognitive Services resource provider. Prereqs on the customer side: 1. **Diagnostic settings** on the Azure OpenAI resource → route metrics to a Log Analytics workspace. 2. Enable the metric categories `InputTokens`, `ProcessedPromptTokens`, `GeneratedTokens` (and optionally `ActiveTokens`). 3. The caller needs `Log Analytics Reader` on the workspace (or `Reader` at the subscription scope). 4. Allow at least 15 minutes for fresh metrics to land in `AzureMetrics`. ### Two bundled queries — pick by metric availability | File | Cached-token derivation | Use when | |------|-------------------------|----------| | `references/queries/default.kql` | `InputTokens − ProcessedPromptTokens` | The standard path. Works on any Cognitive Services deployment with `InputTokens` enabled. | | `references/queries/active_tokens.kql` | `ProcessedPromptTokens − ActiveTokens` | Fallback when `InputTokens` is missing or zero — uses the `ActiveTokens` metric (non-cached tokens) as the subtractor. Some older diagnostic-setting configurations only expose this path. | Pass either with `--kql`: ```bash python references/run_report.py \ --workspace <id> --kql references/queries/active_tokens.kql \ --model gpt-5.4 --out-dir ./report ``` If your workspace uses `AzureDiagnostics` instead of `AzureMetrics`, write a custom KQL that emits the same 4-column schema and pass it with `--kql`. See `docs/sample_kql_queries.md` in the upstream repo for several alternative shapes (request-level breakdown, PTU utilisation, error analysis). --- ## Known caveats - **Pricing drift:** as above — re-vendor `models.json` when upstream bumps. `upstream-pin.md` tracks the SHA. - **`AzureMetrics.Dimensions` shape varies** by API version — the bundled default KQL coalesces `DimensionJson`, `Dimensions`, and `Tags`, which covers everything we've seen. If you see empty `ModelDeploymentName` after a query, dump the raw row and adjust. - **Synthetic generator's anchor date is `2026-01-19`** (Monday). The synth produces realistic business-hours + weekend + burst patterns starting from that fixed timestamp — useful for reproducible demos, but obvious if you ship a customer report without disclosing it. - **`data.py` + `queries/*.kql` are frozen at `e1786f8`** — upstream removed the live Log-Analytics / KQL path (commit `14a5bec`); this skill keeps it for `--workspace` mode, so those files are **not** re-vendored from newer SHAs (only `analysis.py` / `formatting.py` / `models.json` are). The `data.py` Streamlit strip is part of that frozen baseline; the validation script catches any reintroduction because the import would fail outside a Streamlit context. See `upstream-pin.md` KI-002. --- ## References - Upstream repo: <https://github.com/aiappsgbb/ptu-paygo-mix> (SHA pinned in `references/upstream-pin.md`) - Azure OpenAI PTU docs: <https://learn.microsoft.com/azure/ai-services/openai/how-to/provisioned-throughput-onboarding> - AzureMetrics schema: <https://learn.microsoft.com/azure/azure-monitor/reference/tables/azuremetrics> - Related awesome-gbb skills: `azure-tenant-isolation` (for `--workspace` runs), `foundry-observability` (downstream consumers of the JSON report).
Auf GitHub ansehen