gpu-clean-conversion

gpu-clean-conversion is a skill for Claude Code, Codex from google-ai-edge/litert-samples. It costs 76 tokens per session (2,568 once invoked), scanned A, original, Apache-2.0.

A workflow for converting PyTorch or Hugging Face machine-learning models into LiteRT models that run on a device's GPU. It also checks that the converted model produces the same results as the source model.

In plain words
What is it for?
Use it to convert a model, find operations that prevent GPU compilation, detect CPU fallback, and compare device output with a CPU or PyTorch reference.
Why use it?
A model can appear to use the GPU while some operations run on the CPU or return incorrect numbers. This workflow checks conversion, GPU placement, and numerical correctness separately.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one.

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add skills/google-ai-edge/litert-samples/gpu-clean-conversion
Any agent
npx skills add google-ai-edge/litert-samples --skill gpu-clean-conversion
Clone the repo
git clone --depth 1 https://github.com/google-ai-edge/litert-samples

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for gpu-clean-conversion

README.md
[![agentmods](https://agentmods.dev/badge/skills/google-ai-edge/litert-samples/gpu-clean-conversion.svg)](https://agentmods.dev/skills/google-ai-edge/litert-samples/gpu-clean-conversion)
Your own site
<a href="https://agentmods.dev/skills/google-ai-edge/litert-samples/gpu-clean-conversion"><img src="https://agentmods.dev/badge/skills/google-ai-edge/litert-samples/gpu-clean-conversion.svg" alt="Measured on agentmods" height="20"></a>
Per session 76 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,568 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00076 $0.02568
Opus 5 $0.00038 $0.01284
Sonnet 5 $0.00015 $0.00514
Haiku 4.5 $0.00008 $0.00257

Measured 6d ago against content hash 08bdb7b8afb2, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-05, from the pricing page.

Security

Grade A, and why

gpu-clean-conversion scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 6d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

skills/gpu-clean-conversion/SKILL.md · 122 lines

How it starts

The opening of the file, as written. The whole thing — 122 lines — stays where its author put it; the contents beside it link to each section on GitHub.

GPU-clean conversion

A conversion is done when three things hold, in this order:

  1. it converts,
  2. every node runs on the GPU,
  3. the on-device output matches the source model.

Step 3 is not implied by step 2. The delegate can report full residency and still return wrong numbers — that is the failure mode most of the rewrites below exist for. Never call a model done without a numerical check against CPU or PyTorch on the actual device.

Loop

1. Convert plain first. No patches. This tells you what the model actually needs rather than what you assumed.

2. Verify through the CompiledModel API before touching a device.

from litert_gpu_toolkit import check_gpu_compatibility, print_report
print_report(check_gpu_compatibility("model.tflite"))

It compiles the model for the GPU accelerator, runs every signature on random inputs, and compares the outputs against a CPU-compiled reference. A failed GPU compile names the offending op — route it through the table below. A pass with a CPU-fallback warning means some ops fell back to the CPU; treat them the same way if you need full residency. This exercises the host GPU, so step 5 on the actual device is still required.

3. Map each symptom to a rewrite. The rewrites live in utilities/litert_gpu_toolkit — plain Python, no build step. Outside this repo, clone litert-samples and put utilities/ on PYTHONPATH, or vendor the directory:

What you see Rewrite
GATHER_ND named in the compile error Find its source. Stride-2 slicing (x[:, ::2], Focus stems, patch merging), grid_sample, MaxPool padding, bicubic interpolate, and reflect-mode F.pad all lower to it. patch_grid_sample, patch_maxpool_zeropad, patch_interpolate, patch_patch_merging
A rank-5+ tensor named in the compile error PixelShuffle (rank-6 reshape), windowed attention, einops.rearrange, packed-QKV attention head splits. pixelshuffle_to_conv_transpose, patch_window_attention, patch_einops
TRANSPOSE_CONV rejected Version skew, not a missing op. ZeroStuffConvT1d / ZeroStuffConvT2d — zero-stuff plus a plain conv, exact to ~1e-7
SELECT / SELECT_V2 PReLU, ELU, in-place index assignment, and torch.where masking. Replace with arithmetic: x*(1-m) + v*m
BROADCAST_TO Two cases. On a compile-time constant: an outer product or .expand that did not fold — bake the result as a constant at its target shape. On a runtime tensor the GPU delegate rejects it outright, even at rank 4 — the canonical case is GQA's repeat_kv (x[:,:,None].expand(...), which is also rank-5, so two walls in one line). Exact rewrite: torch.cat([x[:, i:i+1].expand(b, n_rep, s, d) for i in range(n_kv)], dim=1) — same head order, bit-exact. Tracked upstream: google-ai-edge/LiteRT#9191
Masked attention wrong only on device: token 0 bit-exact, every later token wrong Broadcast ADD whose LHS is a BATCH_MATMUL result (the scores + mask[1,1,S,S] idiom) silently miscomputed on older runtimes (fixed in newer; head-axis size-1 broadcast only). The signature mimics broken RoPE — tap the rope output before blaming it. Rewrites: pre-expand the mask to [1,H,S,S], or materialize the BMM as a second output
An ADD result that is both a graph output and consumed downstream comes back wrong Output aliasing: the returned tensor holds an operand, not the sum — ADD with two runtime operands (SUB/MUL exact, x + 1.0 exact). This is the shape of every explicit state update in a streaming/recurrent graph. Workaround: emit acc * one where one is a runtime input holding 1.0 — a constant folds straight back into the pattern. Tracked upstream: google-ai-edge/LiteRT#8599
RELU_0_TO_1 rejected by the GPU delegate Emitted by hard-sigmoid / nn.Hardtanh(0,1). Accepted in litert 2.1.3, rejected from 2.1.5 on — a model at full residency on an older runtime hard-fails CompiledModel creation after an upgrade. Rewrite: relu(x) - relu(x-1), exact. Tracked upstream: google-ai-edge/LiteRT#8598
DIV: No support of few identical inputs / Expected 1 const input tensor(s), device only The delegate declines an op whose two inputs are the same tensor, and ops whose inputs are all constants — together these split a perceiver-style block (softmax over a length-1 axis of a constant latent bank) into several partitions. Fixes: special-case the degenerate axis (a softmax over a length-1 axis is identically 1), or make one input non-constant. Note the sibling LayerNorm-over-a-constant pattern no longer reaches the delegate at all — the converter folds it to a single MUL. Tracked upstream: google-ai-edge/LiteRT#9192
NHWC node rewriter not found: amax x.amax(...)/x.max(dim) in stable-softmax, adaptive norms, qk-norm. Rewrite channel reduce-max as max_pool2d(x.reshape(N,1,C,H*W), kernel=(C,1)) — numerically identical — or drop the norm to 3D
Lowering not found: aten._fft_r2c / aten.complex torch.stft/istft and complex views have no lowering (fails before any GPU check). A DFT is a fixed linear map: windowed-DFT as Conv1d with the cos/sin basis baked into kernels (stride = hop), iSTFT as inverse-DFT matmul + overlap-add via zero-stuffed conv-transpose — exact. Model-selection corollary: prefer time-domain vocoder branches over iSTFT-based ones. ⚠ Library STFT-as-conv stacks (torchlibrosa-style) have numerically mis-converted (corr 0.83) while the op check looks clean — verify the spectrogram numerically or compute log-mel host-side
Compiles, runs, output is wrong or NaN The fp16 reduction family — and the trigger is the fp16 accumulator passing 65504, so a plain single-axis mean/sum over enough elements overflows just like variance does. patch_safe_layernorm, patch_rmsnorm, patch_instance_norm, hierarchical_mean. Caveats: at extreme magnitudes (|x| in the thousands) even the adaptive safe-LN form overflows when it reconstructs the large variance — the robust form stays entirely in the down-scaled domain (xs = x/S, normalize xs, never multiply the variance back by ); hierarchical_mean is exact only for power-of-two spatial dims (for arbitrary dims, cascade /2 avg-pools with ceil_mode so each stage averages ≤~49 elements). Diagnostic split: all-zero/all-blank output = an overflow in one block; a result that starts near-correct and degrades with depth = precision compounding, which no overflow patch (and no fp32-precision flag) fixes
Head outputs exactly zero RMSNorm Σx² overflowed fp16 to inf. patch_rmsnorm

Read the full file on GitHub · 122 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 6d ago First seen · 122 lines · 76 tokens per session scan A 08bdb7b8afb2

Subscribe to this mod's changes

gpu-clean-conversion is a skill published in the GitHub repository google-ai-edge/litert-samples (417 stars, last pushed 2d ago), licensed Apache-2.0. It adds 76 tokens to every session and 2,568 once invoked, about $0.0004 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other skills, from other repositories

adversarial-ml-evasion

Craft adversarial examples that cause trained ML classifiers to misclassify at inference time — image recognition, malware detectors, IDS, spam filters.

PurpleAILAB/Decepticon · 36 tokens

llm-redteam-overview

LLM red team category — full AATMF v3 tactic coverage (T01–T15). Routing skill: read this first to identify which tactic applies, then load the matching sub-skill. Maps to MITRE ATLAS where overlap exists.

PurpleAILAB/Decepticon · 58 tokens

misinformation

Hunt LLM misinformation / overreliance (OWASP LLM09:2025) — confident-but-wrong outputs that flow into downstream automated decisions, compliance reports, customer communications, or autonomous code commits without verification.

PurpleAILAB/Decepticon · 49 tokens

sensitive-information-disclosure

Hunt LLM sensitive-information disclosure (OWASP LLM02:2025) — leakage of PII, secrets, internal source, model details, and other-tenant data through model outputs, training-data extraction, or retrieval-side joins.

PurpleAILAB/Decepticon · 55 tokens

vector-and-embedding-weaknesses

Hunt vector / embedding weaknesses (OWASP LLM08:2025) — adversarial inputs against the RAG / similarity layer that cause cross-tenant leak, embedding-inversion privacy loss, semantic confusion, and retriever-driven prompt injection.

PurpleAILAB/Decepticon · 59 tokens

aatmf-t12-rag-poisoning

AATMF T12 — RAG & Knowledge Base Manipulation. PoisonedRAG, vector store flood, embedding collision, retrieval-bias attacks.

PurpleAILAB/Decepticon · 41 tokens