Lightweight auto-tuning framework for Pallas kernels on Google TPU
Project description
pallas-forge
A lightweight auto-tuning framework for Pallas kernels on Google TPU.
pallas-forge helps you systematically discover why some kernel configurations outperform others by 3-5x, producing performance heatmaps, XProf profiler traces, and roofline charts.
Features
- 3 reference kernels with progressive complexity:
- Tiled MatMul (compute-bound, MXU-dominated)
- Fused RMSNorm + Residual (memory-bound, VPU-dominated)
- Fused SwiGLU / GeGLU (compute-bound, fused activation)
- Auto-tuning framework — grid search and random search over block sizes, grid dims, pipeline stages
- Performance heatmaps — visual proof of how parameter choices affect throughput
- XProf integration — capture and compare profiler traces for top configurations
- Roofline analysis — classify kernels as compute-bound or memory-bound
- CPU testing — all kernels run on CPU via Pallas interpret mode (no TPU required for development)
Installation
From PyPI (once published)
pip install pallas-forge # CPU interpret mode
pip install "pallas-forge[viz]" # with matplotlib/seaborn for heatmaps
pip install "pallas-forge[tpu]" # on a Linux TPU VM
From source
git clone https://github.com/nklinh91/pallas-forge
cd pallas-forge
# Basic install (CPU testing via interpret mode)
pip install -e .
# With development tools + visualization
pip install -e ".[dev,viz]"
# On a Linux TPU VM (libtpu is Linux-only)
pip install -e ".[all,tpu]"
Tip: Create a dedicated conda env first to avoid polluting your base environment:
conda create -n pallas-forge python=3.11 -y conda activate pallas-forge pip install -e ".[dev,viz]"
Quick Start
Auto-tune a kernel
import jax
import jax.numpy as jnp
from pallas_forge import tiled_matmul
from pallas_forge.tune import tune, TuneConfig
# Define config space
config = TuneConfig.from_dict({
"block_m": [64, 128, 256],
"block_k": [64, 128],
"block_n": [64, 128, 256],
})
# Define inputs
M, K, N = 2048, 2048, 2048
def input_fn(cfg):
key = jax.random.PRNGKey(0)
x = jax.random.normal(key, (M, K), dtype=jnp.bfloat16)
w = jax.random.normal(key, (K, N), dtype=jnp.bfloat16)
return (x, w)
# Define kernel wrapper
def kernel_fn(x, w, *, block_m, block_k, block_n):
return tiled_matmul(x, w, block_m=block_m, block_k=block_k, block_n=block_n)
# Run auto-tuning
report = tune(kernel_fn, input_fn, config)
# Export results
report.to_csv("results.csv")
report.heatmap("block_m", "block_n", save_path="heatmap.png")
# Best config
best = report.best(1)[0]
print(f"Best: {best.config} -> {best.median_ms:.3f} ms")
print(f"Speedup range: {report.speedup_range:.1f}x")
Use a kernel directly
from pallas_forge import tiled_matmul, fused_rmsnorm_residual, fused_swiglu
# MatMul
result = tiled_matmul(x, w, block_m=128, block_k=128, block_n=128)
# Fused RMSNorm + Residual
normed, new_residual = fused_rmsnorm_residual(x, residual, weight)
# Fused SwiGLU
output = fused_swiglu(x, w_gate, w_up, block_m=128, block_n=256)
Roofline analysis
from pallas_forge.profile import roofline_chart, TPU_SPECS
tpu = TPU_SPECS["v4"] # or "v5e", "v5p"
roofline_chart(
report.results,
peak_tflops=tpu["peak_tflops_bf16"],
peak_bandwidth_gb_s=tpu["peak_bandwidth_gb_s"],
save_path="roofline.png",
)
Requires flops_fn and bytes_fn to be passed to tune() so TFLOPS and bandwidth get populated.
XProf trace capture for top configurations
report = tune(
kernel_fn, input_fn, config,
top_n_traces=3,
trace_output_dir="./xprof_traces",
)
# Open traces in TensorBoard: tensorboard --logdir ./xprof_traces
Project Structure
pallas_forge/
_compat.py # CPU/TPU compatibility (interpret mode)
kernels/
matmul.py # Tiled MatMul
rmsnorm.py # Fused RMSNorm + Residual
swiglu.py # Fused SwiGLU / GeGLU
tune/
__init__.py # tune() entry point
config.py # TuneConfig search space
search.py # GridSearch, RandomSearch
runner.py # BenchmarkRunner with proper timing
report.py # JSON/CSV export + heatmaps
trace.py # XProf trace capture
profile/
roofline.py # Roofline chart generation
analysis.py # Utilization analysis
benchmarks/ # Benchmark scripts per kernel
tests/ # Correctness tests (run on CPU)
Running Tests
# All tests (run on CPU via Pallas interpret mode — no TPU required)
pytest tests/ -v
All 54 tests should pass on CPU. Tests marked @requires_tpu are skipped
automatically when no TPU is detected.
Running Benchmarks (requires TPU)
# Individual kernel
python benchmarks/bench_matmul.py
# All benchmarks
python benchmarks/run_all.py
Outputs (CSV/JSON results + PNG heatmaps) land in results/.
Notebooks
Interactive walkthroughs in notebooks/ — each includes a Colab setup cell so
you can run them on a free TPU runtime.
| Notebook | Focus |
|---|---|
01_tiled_matmul.ipynb |
BlockSpec, grid, block sizes, bfloat16 |
02_fused_rmsnorm.ipynb |
Kernel fusion, VPU vs MXU, HBM traffic |
03_swiglu_geglu.ipynb |
Compute-bound fusion, SwiGLU vs GeGLU |
04_auto_tuning.ipynb |
tune(), heatmaps, random search, YAML configs |
Supported TPU generations
pallas_forge.profile.TPU_SPECS provides hardware presets for roofline analysis:
| Generation | Peak bf16 TFLOPS | Peak HBM GB/s | VMEM (MB) |
|---|---|---|---|
| v4 | 275 | 1200 | 32 |
| v5e | 197 | 819 | 32 |
| v5p | 459 | 2765 | 95 |
Contributing & releases
- Contributing: open an issue or PR. Tests (
pytest tests/) must pass on CPU. - Pre-commit hooks: after
pip install -e ".[dev]", runpre-commit installonce. Ruff and basic hygiene checks will then run on every commit, so you won't push lint-failing code. - Publishing: see
PUBLISHING.mdfor the PyPI release workflow (automated via GitHub Actions + Trusted Publishing). - Changelog: see
CHANGELOG.md.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pallas_forge-0.1.0.tar.gz.
File metadata
- Download URL: pallas_forge-0.1.0.tar.gz
- Upload date:
- Size: 24.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5f674a68e3e07fc01acaba29d93febe618e28bf1b9fccbe4388bdd781d06e140
|
|
| MD5 |
10b28a33091f642632453fc84b669804
|
|
| BLAKE2b-256 |
fd9d9db05ec85982097adfb22df15d88d73c6c4bae73dc547b958d17444518db
|
Provenance
The following attestation bundles were made for pallas_forge-0.1.0.tar.gz:
Publisher:
publish.yml on linhkid/pallas-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pallas_forge-0.1.0.tar.gz -
Subject digest:
5f674a68e3e07fc01acaba29d93febe618e28bf1b9fccbe4388bdd781d06e140 - Sigstore transparency entry: 1340519797
- Sigstore integration time:
-
Permalink:
linhkid/pallas-forge@c4cd9b408be39423ba6195a389b3b8106a1ec2bb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/linhkid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c4cd9b408be39423ba6195a389b3b8106a1ec2bb -
Trigger Event:
push
-
Statement type:
File details
Details for the file pallas_forge-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pallas_forge-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e2ac433ed77ddf2f0fe385a2ea525059d126123e5ba8e18295def87b4c89351
|
|
| MD5 |
beeb407a3d40c3a50240bee5f216f3ff
|
|
| BLAKE2b-256 |
773268a31528cbf25e6e2a20f6e431881fd97274549c07c5fce15a2438388e59
|
Provenance
The following attestation bundles were made for pallas_forge-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on linhkid/pallas-forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pallas_forge-0.1.0-py3-none-any.whl -
Subject digest:
1e2ac433ed77ddf2f0fe385a2ea525059d126123e5ba8e18295def87b4c89351 - Sigstore transparency entry: 1340519807
- Sigstore integration time:
-
Permalink:
linhkid/pallas-forge@c4cd9b408be39423ba6195a389b3b8106a1ec2bb -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/linhkid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c4cd9b408be39423ba6195a389b3b8106a1ec2bb -
Trigger Event:
push
-
Statement type: