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) deterministic ties
argmax / temperature greedy decoding helpers
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 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

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: bf16 support, radix-select top-k/top-p (CUB-class speed), fused sampling (softmax+top-p+draw in one pass), CUDA graph-friendly batching
  • v0.3: INT8/FP8 quantized paths, 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.1.2.tar.gz (119.2 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.1.2-cp310-cp310-manylinux_2_34_x86_64.whl (450.1 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.34+ x86-64

File details

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

File metadata

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

File hashes

Hashes for fusedtok-0.1.2.tar.gz
Algorithm Hash digest
SHA256 96e56aa1b622548a88ab1c6422d171e1355d75399296e776cedcb8d3b44f4f08
MD5 35eff338a5342b200ede0a19e35f3281
BLAKE2b-256 fd519acf8638ceae4b107005e668ff95d3be60f3c271ed152b80cd53e1d4749a

See more details on using hashes here.

Provenance

The following attestation bundles were made for fusedtok-0.1.2.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.1.2-cp310-cp310-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for fusedtok-0.1.2-cp310-cp310-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 1c97be59d1fd7e533862472f6cb6ed0fa86236d80049b1c3075cde360d0ce1b4
MD5 d32930247945d98d46ba28853fb179ad
BLAKE2b-256 2c34d096f83a6024ba16e5a3ea2ba9cff867a6752f737fc751280e8766e49b3d

See more details on using hashes here.

Provenance

The following attestation bundles were made for fusedtok-0.1.2-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

0.2.0

2 files

This release

0.1.2 This release

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