Skip to main content

fusedtok

CI PyPI License: MIT Python 3.10+

Fused CUDA kernels for LLM inference — RMSNorm / RoPE / SwiGLU and friends, with zero-copy torch tensor support: up to 6.2x faster than PyTorch eager (RoPE, RTX 3060, see Benchmarks).

中文文档请看 README_zh.md | English below.

Why

LLM inference frameworks launch many small, memory-bound operators per token. Each launch round-trips through global memory. fusedtok fuses them into single kernels to cut memory traffic and launch overhead.

Operators

Status Kernel Notes
RMSNorm (+residual) LLaMA/Qwen style, fused residual add
LayerNorm with affine
RoPE interleaved and NeoX layouts, kv-cache pos_offset
SwiGLU fused MLP activation
Softmax (row-wise) numerically stable
SiLU / GeLU / GeLU-tanh / ReLU / Tanh / Sigmoid elementwise
add / mul elementwise binary (fused add+residual pattern)
top-k / top-p (nucleus) radix-select, deterministic ties (1.4x vs torch @131k)
argmax / temperature greedy decoding helpers
sample_topp fused nucleus sampling: softmax -> top-p -> seeded draw, one kernel
repetition penalty CTRL-style, applied to sampled token ids
INT8/FP8 quantized path planned v0.3

Install

pip install fusedtok

Prebuilt Linux x86_64 wheels (manylinux, built with CUDA 12.4) are on PyPI. On Windows (or any platform without a matching wheel) pip builds from source automatically:

git clone https://github.com/Hai-Wenxiang/fusedtok.git
cd fusedtok
pip install .

Requirements:

  • NVIDIA GPU of RTX 30 series (Ampere) or newer — e.g. RTX 3060/3090, RTX 4080, RTX 5090, A100, H100
  • CUDA Toolkit >= 12.0
  • A C++17 compiler (MSVC on Windows, GCC/Clang on Linux); Python 3.10+
What is "compute capability"? (click to expand)

Compute capability is NVIDIA's version number for a GPU architecture generation — not a performance score. CUDA code must be compiled for a specific architecture to run on it. The wheel builds native cubins for compute capability 8.0 (A100) and 8.6 (RTX 30) plus a compute_86 PTX fallback, so Ampere runs natively and newer architectures (RTX 40/50, ...) JIT the PTX with their driver.

Compute capability Architecture Example GPUs
7.5 Turing GTX 16xx, RTX 20xx (not supported)
8.0 / 8.6 Ampere A100, RTX 30xx
8.9 Ada RTX 40xx (via PTX)
9.0 Hopper H100 (via PTX)
12.0 Blackwell RTX 50xx (via PTX)

Check yours: run nvidia-smi to see your GPU model, then look it up at https://developer.nvidia.com/cuda-gpus

Usage

numpy in / numpy out, or torch in / torch out — including zero-copy CUDA: kernels read and write torch device buffers directly via data_ptr(), with no staging copies and no host synchronization.

import numpy as np
import torch
import fusedtok

x = np.random.randn(4, 1024).astype(np.float32)
w = np.random.rand(1024).astype(np.float32)

# CPU reference implementation (ground truth, runs anywhere)
y = fusedtok.rmsnorm(x, w, eps=1e-6)

# staged CUDA: copies to GPU, runs kernel, copies back
y = fusedtok.rmsnorm(x, w, cuda=True)

# zero-copy CUDA with torch tensors: kernels run in torch's own buffers,
# stream-ordered with other torch operations
xt, wt = torch.from_numpy(x).cuda(), torch.from_numpy(w).cuda()
yt = fusedtok.rmsnorm(xt, wt)          # -> CUDA torch tensor

# RoPE with kv-cache position offset, NeoX (LLaMA-HF) layout
q = torch.randn(1, 4096, device="cuda")          # new token only
q_rot, k_rot = fusedtok.rope(q, k=None, pos_offset=1023, neox=True)

# sampling side
logits = fusedtok.repetition_penalty(logits, sampled_ids, penalty=1.1)
values, indices = fusedtok.topk(logits, k=50)

Every function accepts float32 numpy arrays or torch tensors (other dtypes are converted with a copy) and returns float32 outputs of the same family. CUDA torch tensors may also be bfloat16 - the kernels compute in float32 and convert at the load/store boundary (norm weights are upcast to float32 automatically; sampling/selection ops stay float32). CUDA torch tensors select the zero-copy path automatically.

See examples/demo.py for a runnable tour of every operator.

Correctness

Every kernel ships with a CPU reference implementation and element-wise parity tests (pytest). Tests run on machines without a GPU (CUDA cases skip automatically).

Benchmarks

RTX 3060 (sm_86), float32, zero-copy torch tensors, CUDA-event timing, vs the equivalent PyTorch eager expressions (full data: docs/benchmark_results.json, reproduce with python benchmarks/bench.py):

Op Shape fusedtok PyTorch eager Speedup
RoPE NeoX (q+k) [2048×4096] 416 µs 2570 µs 6.2x
RMSNorm (+residual) [1024×4096] 260 µs 538 µs 2.1x
SwiGLU [1024×4096] 153 µs 257 µs 1.7x
LayerNorm [1024×4096] 168 µs 162 µs ~1.0x
SiLU [1024×4096] 105 µs 112 µs ~1.0x
Softmax [1024×4096] 159 µs 115 µs 0.7x
argmax [131072] 36 µs 46 µs 1.3x
top-k (k=50) [131072] 168 µs 129 µs 0.8x

fusedtok vs PyTorch eager

RTX 5060 Ti (Blackwell, sm_120) — same suite, torch 2.11/cu128, highlights:

Op Shape fusedtok PyTorch eager Speedup
RoPE NeoX (q+k) [512×4096] 29 µs 240 µs 8.3x
RMSNorm (+residual) [4096×4096] 512 µs 1662 µs 3.3x
Softmax [1024×4096] 20 µs 51 µs 2.6x
SwiGLU [4096×4096] 504 µs 858 µs 1.7x
argmax [32000] 11 µs 22 µs 1.9x
LayerNorm [1024×4096] 27 µs 28 µs ~1.0x

fusedtok vs PyTorch eager (RTX 5060 Ti)

The PyPI wheel ships sm_80/sm_86 cubins plus a compute_86 PTX fallback — verified to JIT and run correctly on Blackwell (sm_120) drivers.

Fusions win big (RoPE / RMSNorm / SwiGLU) because eager mode round-trips intermediate tensors through global memory. Pure memory-bound elementwise ops run at the same ~330-500 GB/s as PyTorch's tuned kernels (silu, gelu, add ≈ parity). Softmax and top-k remain behind PyTorch's CUB-based kernels — honest numbers, on the v0.2 roadmap.

Development

See CONTRIBUTING.md for the full guide (test rules, error contract, determinism invariants). Quick start:

# Windows: run inside a VS developer prompt (vcvars64)
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
# from repo root: PYTHONPATH picks up the built module, conftest.py adds python/
$env:PYTHONPATH = "$PWD/build"        # Windows
PYTHONPATH=$PWD/build                 # Linux
python -m pytest tests -q
python benchmarks/bench.py            # GPU benchmark + chart

Windows / Linux. Windows uses MSVC via nvcc; CI builds and runs the CPU test suite on every push.

Roadmap

  • v0.2 (done): bf16 zero-copy, radix-select top-k/top-p, fused nucleus sampling, single-read softmax, CUDA-graph verified
  • v0.3: INT8/FP8 quantized paths, merge-sort selection (CUB-class), bf16x2 vectorized elementwise, block-size autotuning
  • v0.4+: lightweight fused attention; prebuilt wheels on PyPI

Community

License

MIT — see LICENSE. Third-party notices: NOTICES.md.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fusedtok-0.2.0.tar.gz (203.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fusedtok-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl (545.2 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

File details

Details for the file fusedtok-0.2.0.tar.gz.

File metadata

  • Download URL: fusedtok-0.2.0.tar.gz
  • Upload date:
  • Size: 203.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fusedtok-0.2.0.tar.gz
Algorithm Hash digest
SHA256 84885c82663612125d17de53bbcc90efc2955d973441927ebce7e9e1b410cddc
MD5 8964e980d3377a8092f78528fd462366
BLAKE2b-256 cc2d0beb1fa31a5310c6be68767a806a34c317264f1a8a74c2d8a8198f0b6494

See more details on using hashes here.

Provenance

The following attestation bundles were made for fusedtok-0.2.0.tar.gz:

Publisher: publish.yml on Hai-Wenxiang/fusedtok

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fusedtok-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for fusedtok-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 7640d994e79131e02eda444ea04da8aacd052c0959b24385e4da76370e1590cd
MD5 552a1bad55f9d8e545a157d63d98d79f
BLAKE2b-256 fe2207ce1db545f157979f99d0df6885134d00e264e503caa7ecc88b8de6fcfb

See more details on using hashes here.

Provenance

The following attestation bundles were made for fusedtok-0.2.0-cp310-cp310-manylinux_2_34_x86_64.whl:

Publisher: publish.yml on Hai-Wenxiang/fusedtok

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

This release

0.2.0 This release

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page