diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index de99b2f..aa072d2 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -17,7 +17,8 @@ "./skills/local-ai-use", "./skills/local-ai-app-integration", "./skills/serving-llms-on-instinct", - "./skills/tracelens-analysis-orchestrator" + "./skills/tracelens-analysis-orchestrator", + "./skills/optimizing-models-with-quark" ], "description": "AMD's verified Agent Skills in one plugin: route image/audio through local AI on Ryzen AI, serve LLMs on AMD Instinct GPUs with vLLM, and analyze GPU kernel and PyTorch trace performance." } diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index cd38ee1..8ce306e 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -21,7 +21,8 @@ "./skills/local-ai-use", "./skills/local-ai-app-integration", "./skills/serving-llms-on-instinct", - "./skills/tracelens-analysis-orchestrator" + "./skills/tracelens-analysis-orchestrator", + "./skills/optimizing-models-with-quark" ], "interface": { "displayName": "AMD Skills", diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 62c7697..ab6edea 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -16,7 +16,8 @@ "./skills/local-ai-use", "./skills/local-ai-app-integration", "./skills/serving-llms-on-instinct", - "./skills/tracelens-analysis-orchestrator" + "./skills/tracelens-analysis-orchestrator", + "./skills/optimizing-models-with-quark" ], "description": "AMD's verified Agent Skills in one plugin: route image/audio through local AI on Ryzen AI, serve LLMs on AMD Instinct GPUs with vLLM, and analyze GPU kernel and PyTorch trace performance.", "author": { diff --git a/README.md b/README.md index 310aea0..311322c 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,7 @@ Cross-stack skills, from client to cloud. | `hyperloom-workload-optimizer` | Autonomously optimizes LLM inference on AMD GPUs. | _planned_ | | [`lemonade-router-builder`](skills/lemonade-router-builder/SKILL.md) | Set up a Lemonade model router that handles requests based on content, sensitivity, or required capabilities. | in-repo | | `hrr-replay-analysis` | Record, replay, and analyze GPU workload behavior on ROCm across AMD Instinct, Radeon, and Ryzen hardware using HIP Record and Replay archives. | _planned_ | +| [`optimizing-models-with-quark`](skills/optimizing-models-with-quark/SKILL.md) | Quantize a PyTorch or ONNX model with AMD Quark: fetch Quark's own skill tree on consent, then route to the Torch PTQ, ONNX PTQ, or environment-setup starting point. | in-repo | ### Server-Native diff --git a/skills/optimizing-models-with-quark/SKILL.md b/skills/optimizing-models-with-quark/SKILL.md new file mode 100644 index 0000000..529eb40 --- /dev/null +++ b/skills/optimizing-models-with-quark/SKILL.md @@ -0,0 +1,173 @@ +--- +name: optimizing-models-with-quark +description: >- + Quantizes and optimizes a trained model with AMD Quark by fetching Quark's own + quantization skills and routing the agent to the right one. Use when the user + wants to quantize, compress, or shrink a PyTorch, HuggingFace, safetensors, or + `.onnx` model, or mentions PTQ, post-training quantization, FP8, INT4, INT8, + UINT4, MX, MXFP4, BFP16, XINT8, A8W8, A16W8, KV-cache quantization, AWQ, GPTQ, + SmoothQuant, AdaRound, calibration data, or a quantized checkpoint for vLLM or + Ryzen AI. Also use for "install AMD Quark", "pip install amd-quark", "set up + Quark", or a ModuleNotFoundError for `quark`. Do not use to serve, deploy, or + benchmark an already-quantized model on AMD hardware — see + `serving-llms-on-instinct` or `serving-llms-on-epyc` — and do not use for GPU + kernel profiling, which belongs to `magpie-kernel-evaluator`. +--- + +# Optimizing Models with AMD Quark + +[AMD Quark](https://github.com/amd/Quark) turns a trained PyTorch or ONNX model +into a smaller, faster one through quantization. Quark ships detailed skills for +that work, but they live in the Quark repository and are **not** part of the +`amd-quark` pip package, so an agent cannot reach them by installing the +package. + +This skill is the bridge. It puts Quark's skill tree on disk and names the file +to start reading from. That is all it does: it quantizes nothing itself, it does +not install the pip package, and it registers nothing as a skill. + +**State this consequence to the user once, up front.** The tree is read as +ordinary files. Nothing is registered with the agent harness, so a later +quantization question will not route to a Quark skill on its own — every Quark +task comes back through this entry point. What that buys: nothing is written +into the user's workspace or any skills directory, and no restart is needed. + +Throughout this skill, `` means: + +- Linux / macOS: `~/.cache/amd-quark-skills` +- Windows: `%LOCALAPPDATA%/amd-quark-skills` + +A cache directory, deliberately outside the user's workspace: it keeps their +repository clean, needs no `.gitignore` entry, and is reused across projects. +The commands below spell out the Linux and macOS path; on Windows substitute the +`%LOCALAPPDATA%` one. + +## Step 1: Check whether the tree is already there + +```bash +test -f "$HOME/.cache/amd-quark-skills/.claude/skills-impl/README.md" \ + && echo present || echo missing +``` + +If it prints `present`, go straight to Step 4 — do not re-fetch, and do not ask +the user about fetching. + +## Step 2: Fetch it, with consent + +Tell the user what is about to happen and wait for an explicit yes: + +- a shallow, blobless clone of `https://github.com/amd/Quark` into + ``, a couple of megabytes on disk +- nothing written to their workspace, their repository, or any skills directory +- no packages installed and no environment change + +```bash +git clone --depth 1 --filter=blob:none --sparse \ + https://github.com/amd/Quark.git "$HOME/.cache/amd-quark-skills" +git -C "$HOME/.cache/amd-quark-skills" sparse-checkout set \ + .claude examples/torch/language_modeling/llm_ptq +``` + +Two paths, because two things are needed. `.claude` holds the skills. The +`llm_ptq` example holds `quantize_quark.py`, the script the Torch PTQ workflow +runs — the pip package does not ship it, and without it that workflow stalls at +its first step. + +This clone brings the skills, not the library. Quark itself comes from PyPI as +`pip install amd-quark`, driven by the `quark-install` starting point, never +from ``: the `quark/` package source is outside the two paths above, +so no install run from the cache directory can produce a working Quark. + +Clone the default branch. Do not pin a branch or tag: the default branch tracks +the current Quark release, which is what the installed `amd-quark` package will +match. + +To update an existing tree later: `git -C "$HOME/.cache/amd-quark-skills" pull`. + +## Step 3: Verify before routing + +```bash +cd "$HOME/.cache/amd-quark-skills" && ls \ + .claude/skills-impl/l2-workflows/torch/quark-torch-llm-ptq-workflow/SKILL.md \ + .claude/skills-impl/l2-workflows/onnx/quark-onnx-ptq-workflow/SKILL.md \ + .claude/skills-impl/l1-atomic/shared/quark-install/SKILL.md \ + examples/torch/language_modeling/llm_ptq/quantize_quark.py +``` + +All four must be listed. If any is missing, **stop and report** — do not fall +back to guessing quantization flags from memory, and do not fetch individual +files one at a time. The files reference each other by relative path, so a +partial tree produces broken instructions. Common causes are a proxy blocking +GitHub and a git older than 2.25 (no `sparse-checkout`); see +[reference.md](reference.md). + +## Step 4: Pick the starting point and read it + +| The user wants to | Read this file, relative to `` | +| --- | --- | +| Quantize a PyTorch / HuggingFace / safetensors model | `.claude/skills-impl/l2-workflows/torch/quark-torch-llm-ptq-workflow/SKILL.md` | +| Quantize an `.onnx` model | `.claude/skills-impl/l2-workflows/onnx/quark-onnx-ptq-workflow/SKILL.md` | +| Install or verify the Quark environment | `.claude/skills-impl/l1-atomic/shared/quark-install/SKILL.md` | + +Read the file and follow it as written, including its checkpoints — both PTQ +workflows stop for user confirmation after model intake, after the quantization +plan, and before execution. Honor those stops. + +If the request is ambiguous, ask which model the user has rather than guessing: +a HuggingFace ID or a directory of safetensors goes to the Torch path, a file +ending in `.onnx` goes to the ONNX path. + +## Following references inside the tree + +The starting points are orchestrators. They name other skills by bare name +(`quark-torch-model-intake`, `quark-onnx-quant-plan`, and so on) and expect JSON +artifacts produced by skills further upstream. When a file names a skill you +have not read, **find it in the same tree and read it** — every skill lives at +`.claude/skills-impl////SKILL.md`, so +`quark-torch-model-intake` is at +`.claude/skills-impl/l1-atomic/torch/quark-torch-model-intake/SKILL.md`. +[reference.md](reference.md) lists all of them with their paths. + +Two things follow from that: + +- The workflows say *"if any upstream artifact is missing, stop and name the + missing producer skill."* When that happens, the fix is to read the producer + skill in the tree, not to invent the artifact. +- The Torch workflow's first step tells you to locate `quantize_quark.py`, with + a `find /` fallback. Skip the search: it is already at + `/examples/torch/language_modeling/llm_ptq/quantize_quark.py`. + +## Environment gaps worth pre-empting + +Both PTQ paths assume a working environment and will bounce to a setup skill the +user has not heard of. Say so before it happens, so an unfamiliar skill name +does not read as a failure: + +- **`quark-install` expects PyTorch to already be installed and verified.** If + it is not, that skill hands off to `quark-torch-install`, which is the right + order — Quark builds against the installed torch. +- **The ONNX path needs ONNX Runtime**, recorded in `onnx_install_result.json` + and produced by `quark-onnx-install`. In `quark-install`, ONNX Runtime is only + an optional section, so a user who ran just `quark-install` will still be sent + to `quark-onnx-install`. + +## Rules + +- **The library comes from PyPI, the skills come from git.** `pip install + amd-quark`, or the matching pre-built wheel from the AMD package index, is the + install path this entry point endorses. `quark-install` also documents a + from-source option; take it only when the user explicitly asks for it. +- **Treat `` as read-only.** Quark's own skills forbid modifying + upstream code, examples, and tutorials. Generated quantization scripts, output + models, and artifacts go in the user's working directory, never in the cache. +- **Never fetch skill files one at a time.** The tree is the unit; relative + references between files are why. +- **Never substitute your own quantization advice for the tree's.** If the tree + is unavailable, say so and stop, rather than improvising flags for + `quantize_quark.py` or a `QConfig`. +- **Do not copy the tree into the user's workspace or a skills directory**, and + do not ask them to restart the agent. Reading files in place is the whole + design. + +For skill-by-skill paths, the artifact contracts, cache maintenance, and +troubleshooting, see [reference.md](reference.md). diff --git a/skills/optimizing-models-with-quark/reference.md b/skills/optimizing-models-with-quark/reference.md new file mode 100644 index 0000000..1b44645 --- /dev/null +++ b/skills/optimizing-models-with-quark/reference.md @@ -0,0 +1,234 @@ +# Reference + +Detail behind [SKILL.md](SKILL.md): what the fetched tree contains, which file +answers which question, and what to do when the fetch or a read fails. + +- [The cache directory](#the-cache-directory) +- [How the tree is organized](#how-the-tree-is-organized) +- [The three starting points](#the-three-starting-points) +- [Skills reachable from the starting points](#skills-reachable-from-the-starting-points) +- [Artifacts passed between skills](#artifacts-passed-between-skills) +- [Environment dependency chains](#environment-dependency-chains) +- [Worked examples inside the tree](#worked-examples-inside-the-tree) +- [Maintaining the cache](#maintaining-the-cache) +- [Troubleshooting](#troubleshooting) + +## The cache directory + +`` is `~/.cache/amd-quark-skills` on Linux and macOS, or +`%LOCALAPPDATA%/amd-quark-skills` on Windows. It holds a shallow, blobless, +sparse clone of `https://github.com/amd/Quark` containing two paths: + +| Path | Why it is there | +| --- | --- | +| `.claude/` | Quark's skills | +| `examples/torch/language_modeling/llm_ptq/` | `quantize_quark.py`, the script the Torch PTQ workflow runs, plus its `requirements.txt` and reference docs | + +Together with the git metadata that is a couple of megabytes on disk. + +The location is deliberate. A cache directory keeps the user's repository clean, +survives across projects, and is a single `rm -rf` to undo. Nothing is copied +into the workspace and nothing is registered as a skill. + +The clone tracks Quark's default branch, which is the current release branch, so +the tree stays aligned with the `amd-quark` build that `pip install amd-quark` +produces. Do not pin a branch or tag. + +## How the tree is organized + +Quark's skills sit in two layers. `.claude/skills/` holds thin stubs whose only +content is a pointer; `.claude/skills-impl/` holds the real bodies. This skill +routes straight to `skills-impl` and ignores the stubs. + +Inside `skills-impl`, every skill is at +`///SKILL.md`, where backend is `shared`, `torch`, +or `onnx`. The layers, from the ground up: + +| Layer | Role | +| --- | --- | +| `l0-foundation` | Environment and workspace facts. No quantization logic. | +| `l1-atomic` | Single-responsibility steps with explicit inputs, outputs, and recovery behavior. | +| `l2-workflows` | Orchestrators that chain atomic skills, manage checkpoints, and hand off artifacts. | +| `l3-recipes` | Named compositions that configure and combine an L2 workflow for a specific goal. | + +`skills-impl/shared/` is not a skill layer: it holds the JSON schemas and +templates the skills refer to. The tree also carries a maintenance layer used by +Quark's own developers to keep their skills in sync with the codebase; it plays +no part in quantizing a model, so leave it alone. + +## The three starting points + +Paths are relative to ``. + +**PyTorch / HuggingFace / safetensors PTQ** — +`.claude/skills-impl/l2-workflows/torch/quark-torch-llm-ptq-workflow/SKILL.md` + +Four steps with a user checkpoint after each: model intake, quantization plan, +manifest generation, then execution of `quantize_quark.py`. Stops at the +quantized model. Covers FP8, INT4/UINT4 weight-only, INT8, and AMD FP4, with +optional AWQ, GPTQ, or SmoothQuant, and FP8 KV-cache quantization. + +**ONNX PTQ** — +`.claude/skills-impl/l2-workflows/onnx/quark-onnx-ptq-workflow/SKILL.md` + +Same four-step shape, but there is no shipped script for ONNX. Step 3 generates +a standalone Python script in the user's working directory that imports from +`quark.onnx`, and step 4 runs it. Covers the XINT8, A8W8, A16W8, BF16, BFP16, +and MX presets, with CLE, AdaRound, and AdaQuant as accuracy algorithms. + +**Environment setup** — +`.claude/skills-impl/l1-atomic/shared/quark-install/SKILL.md` + +Installs and verifies `amd-quark`: the universal wheel by default, the AMD index +pre-built wheels as the alternative when a C++ compiler is unwanted, plus +Python version limits, ONNX Runtime bounds, and LLM PTQ extras. + +## Skills reachable from the starting points + +Every path below is relative to `/.claude/skills-impl/` and ends in +`SKILL.md`. Read one when a starting point names it, not before. + +**`l0-foundation/shared/`** + +| Skill | What it does | +| --- | --- | +| `quark-env-preflight` | Detects OS, Python, accelerator, and GPU. Produces `env_context.json`. | +| `quark-workspace-validate` | Validates the paths a run will read and write. Produces `workspace_context.json`. | + +**`l1-atomic/shared/`** + +| Skill | What it does | +| --- | --- | +| `quark-install` | Installs and verifies the `amd-quark` package and its dependencies. Produces `quark_install_result.json`. | + +**`l1-atomic/torch/`** + +| Skill | What it does | +| --- | --- | +| `quark-torch-install` | Installs PyTorch matched to the accelerator. Produces `pytorch_install_result.json`. | +| `quark-torch-router` | Routes a Torch-side request to the right skill. Produces `session_context.json`. | +| `quark-torch-model-intake` | Parses the model config without loading weights, matches supported templates, flags risks such as MoE, very large models, and transformers version constraints. Produces `model_analysis.json`. | +| `quark-torch-quant-plan` | Chooses scheme, KV-cache scheme, exclude list, algorithm, and calibration settings. Produces `quant_plan.json`. | +| `quark-torch-result-validator` | Verifies the quantized output and the exported weights. | +| `quark-torch-debug` | Diagnoses Torch tracebacks, failed PTQ runs, and CUDA / ROCm out-of-memory errors. | +| `quark-torch-export` | Exports a quantized model to ONNX, JSON-safetensors, or GGUF. | +| `quark-torch-llm-eval` | Evaluates a model, for example perplexity or GSM8K / MMLU. | + +**`l1-atomic/onnx/`** + +| Skill | What it does | +| --- | --- | +| `quark-onnx-install` | Installs ONNX Runtime within Quark's supported range, CPU or GPU variant. Produces `onnx_install_result.json`. | +| `quark-onnx-router` | Routes an ONNX-side request and marks the backend in `session_context.json`. | +| `quark-onnx-model-intake` | Reads the graph: opset and IR version, input and output shapes, op histogram, whether QDQ nodes already exist, external-data status, deployment-target compatibility. Produces `model_analysis.json`. | +| `quark-onnx-quant-plan` | Chooses the preset, calibration method, and `algo_config`. Produces `quant_plan.json`. | +| `quark-onnx-result-validator` | Checks the quantized `.onnx`: QDQ insertion and initializers. | +| `quark-onnx-debug` | Diagnoses `quantize_static` failures, unavailable execution providers, and custom-op library load errors. | + +**`l2-workflows/`** — `torch/quark-torch-llm-ptq-workflow` and +`onnx/quark-onnx-ptq-workflow`, the two PTQ starting points above. + +**`l3-recipes/`** + +| Skill | What it does | +| --- | --- | +| `torch/quark-torch-llm-ptq-eval` | Torch PTQ plus validation plus evaluation in one pass. Use when the user wants accuracy numbers, not just a quantized model. | +| `onnx/quark-onnx-autosearch-pro` | Searches for a quantization configuration instead of fixing one up front. Use for "auto search" or "find the best config". | + +## Artifacts passed between skills + +Skills communicate through files, and a workflow stops when one it needs is +absent. Their JSON schemas live in +`.claude/skills-impl/shared/contracts/`. + +| Artifact | Produced by | +| --- | --- | +| `env_context.json` | `quark-env-preflight` | +| `workspace_context.json` | `quark-workspace-validate` | +| `session_context.json` | `quark-torch-router` / `quark-onnx-router` | +| `pytorch_install_result.json` | `quark-torch-install` | +| `quark_install_result.json` | `quark-install` | +| `onnx_install_result.json` | `quark-onnx-install` | +| `model_analysis.json` | `quark-torch-model-intake` / `quark-onnx-model-intake` | +| `quant_plan.json` | `quark-torch-quant-plan` / `quark-onnx-quant-plan` | +| `run_manifest.yaml` | either PTQ workflow, at its manifest checkpoint | +| `validation_report.md` | the result validators | + +When a workflow reports a missing artifact, it names the skill that produces it. +Read that skill in the tree and run it. Do not hand-write the artifact: the +workflows explicitly forbid improvising a partial one, because downstream steps +trust its contents. + +## Environment dependency chains + +**Torch PTQ** needs, in order: `quark-env-preflight` → +`quark-torch-install` → `quark-install`. Quark builds against the installed +PyTorch, so torch comes first; `quark-install` refuses to proceed and hands off +to `quark-torch-install` if PyTorch is missing or mismatched. + +**ONNX PTQ** needs the same chain plus `quark-onnx-install`. ONNX Runtime is +only an optional section of `quark-install`, so a user who ran just +`quark-install` still lands in `quark-onnx-install` when the ONNX workflow looks +for `onnx_install_result.json`. + +Two footguns Quark's skills call out and worth repeating here: the universal +PyPI wheel compiles its kernels on first import and therefore needs a C++ +compiler, which the AMD index pre-built wheels avoid; and on ROCm, pin the GPU +with `HIP_VISIBLE_DEVICES` rather than `CUDA_VISIBLE_DEVICES`, even though +`--device cuda` remains the correct flag on ROCm torch. + +## Worked examples inside the tree + +Both PTQ workflows ship a full walkthrough beside their `SKILL.md`, with real +commands, real numbers, and the expected output layout. They are the fastest way +to see what a run produces: + +- `.claude/skills-impl/l2-workflows/torch/quark-torch-llm-ptq-workflow/example-fp8-qwen3-8b.md` +- `.claude/skills-impl/l2-workflows/onnx/quark-onnx-ptq-workflow/example-xint8-yolov8n.md` + +## Maintaining the cache + +```bash +# Update to the current Quark release +git -C "$HOME/.cache/amd-quark-skills" pull + +# Check what was fetched +git -C "$HOME/.cache/amd-quark-skills" sparse-checkout list + +# Remove it entirely +rm -rf "$HOME/.cache/amd-quark-skills" +``` + +Refresh when the user upgrades `amd-quark`, or when a skill in the tree +describes a flag the installed package rejects. Removing the directory is always +safe: the next run re-fetches it, and nothing else depends on it. + +## Troubleshooting + +**`git: 'sparse-checkout' is not a git command`** — git is older than 2.25. +Upgrade git. As a fallback, a full `git clone --depth 1` of the repository works +and costs a few MB more; the file paths are unchanged. + +**Clone fails or hangs** — the host cannot reach `github.com`. Check the proxy +environment (`https_proxy`, `HTTPS_PROXY`) and try +`git ls-remote https://github.com/amd/Quark`. Report the failure and stop; do +not fall back to quantization advice from memory, and do not fetch raw file URLs +one at a time — the skills reference each other by relative path, so isolated +files are not usable. + +**Clone succeeded but Step 3 lists no files** — the sparse-checkout patterns did +not apply. Re-run the `sparse-checkout set` command from +[SKILL.md](SKILL.md), then verify with `sparse-checkout list`. + +**A skill names a file that does not exist** — Quark's skills cite their sources +with repo-root-relative paths such as `docs/source/install.rst` or +`quark/onnx/quantization/config/custom_config.py`. Those are provenance notes, +and they are outside the two paths fetched here. Nothing needs to be read from +them: the skill body already inlines what it needs. If a step genuinely requires +another part of the Quark repository, add it with +`git -C "$HOME/.cache/amd-quark-skills" sparse-checkout add ` rather than +cloning the whole thing again. + +**A quantization run fails** — that is the tree's job, not this skill's. Read +`quark-torch-debug` or `quark-onnx-debug` from the paths listed above and follow +it. diff --git a/skills/optimizing-models-with-quark/skill-card.md b/skills/optimizing-models-with-quark/skill-card.md new file mode 100644 index 0000000..8320309 --- /dev/null +++ b/skills/optimizing-models-with-quark/skill-card.md @@ -0,0 +1,18 @@ +# Skill Card + +## Description + +Entry point that connects an agent to AMD Quark's own quantization skills. On +consent it fetches Quark's skill tree from the Quark repository into a cache +directory outside the user's workspace, then routes the agent to one of three +starting points: PyTorch / HuggingFace PTQ, ONNX PTQ, or Quark environment +setup. It quantizes nothing itself and installs nothing as a skill — the +quantization knowledge stays upstream in Quark, versioned with the product. + +## Owner + +AMD + +## License + +MIT