Spaces:
Running on Zero
Running on Zero
Download rtcwm/model/fp8.py from hugging-apps/streaming-code-world-model: direct link, hf CLI and curl.
- Browser
- Download file 1.96 kB
-
https://huggingface.co/spaces/hugging-apps/streaming-code-world-model/resolve/main/rtcwm/model/fp8.py
- Command line
-
hf download hf://spaces/hugging-apps/streaming-code-world-model/rtcwm/model/fp8.py
-
curl -L -o fp8.py https://huggingface.co/spaces/hugging-apps/streaming-code-world-model/resolve/main/rtcwm/model/fp8.py
1.96 kB
| """FP8 linears for sampling (Hopper): the large bias-free linears of every DiT block -- attention qkv / out | |
| and the MLP -- with e4m3 weights scaled per output channel and activations quantized per row on the fly, | |
| multiplied by torch._scaled_mm into bf16. Inference only (no gradient), on a model whose LoRA is merged; | |
| approximate (FP8 rounding), so its effect is measured, not assumed (tests/test_fp8.py). | |
| """ | |
| from __future__ import annotations | |
| import torch | |
| from torch import nn | |
| E4M3_MAX = 448.0 | |
| class FP8Linear(nn.Module): | |
| def __init__(self, linear: nn.Linear): | |
| super().__init__() | |
| assert linear.bias is None | |
| w = linear.weight.detach().float() # [out, in] | |
| scale = (w.abs().amax(dim=1, keepdim=True) / E4M3_MAX).clamp_min(1e-12) | |
| self.register_buffer("weight_fp8", (w / scale).to(torch.float8_e4m3fn), persistent=False) | |
| self.register_buffer("weight_scale", scale.t().contiguous(), persistent=False) # [1, out] | |
| self.out_features = linear.out_features | |
| def forward(self, x): | |
| shape = x.shape | |
| x2 = x.reshape(-1, shape[-1]) | |
| scale = (x2.abs().amax(dim=1, keepdim=True).float() / E4M3_MAX).clamp_min(1e-12) # [rows, 1] | |
| xq = (x2.float() / scale).to(torch.float8_e4m3fn) | |
| y = torch._scaled_mm(xq, self.weight_fp8.t(), scale_a=scale, scale_b=self.weight_scale, | |
| out_dtype=torch.bfloat16) | |
| return y.reshape(*shape[:-1], self.out_features) | |
| def quantize_blocks(model) -> int: | |
| """Swap the DiT blocks' qkv / out / fc1 / fc2 linears for FP8Linear in place; returns how many.""" | |
| n = 0 | |
| for block in model.blocks: | |
| for parent, names in ((block.attn, ("qkv_proj", "out_proj")), (block.mlp, ("fc1", "fc2"))): | |
| for name in names: | |
| setattr(parent, name, FP8Linear(getattr(parent, name))) | |
| n += 1 | |
| torch.cuda.empty_cache() | |
| return n | |