Buckets:
| """Single-variant CUDA memory probe (Claims 2 & 3). ONE variant per process, | |
| per the authors' own benchmarking guidance (flashoptim issue #1). | |
| Prints exactly one JSON line: bytes for params / grads / optimizer state and | |
| steady-state peak, plus bytes-per-parameter for each. | |
| Variants: | |
| ref fp32 params + torch.optim.AdamW + bf16 autocast fwd/bwd (paper Reference) | |
| flash cast_model bf16 + FlashAdamW(master_weight_bits=24, quantize=True) | |
| flash_gr flash + enable_gradient_release | |
| split_only cast_model bf16 + FlashAdamW(quantize=False, master_weight_bits=24) | |
| quant_only fp32 params + FlashAdamW(quantize=True) (master bits N/A on fp32) | |
| """ | |
| import argparse | |
| import gc | |
| import json | |
| import sys | |
| import torch | |
| def build_model(name: str): | |
| if name == "resnet50": | |
| import torchvision | |
| m = torchvision.models.resnet50() | |
| x = torch.randint(0, 255, (8, 3, 224, 224), dtype=torch.uint8) | |
| inp = (x.cuda().to(torch.float32) / 255.0,) | |
| tgt = torch.randint(0, 1000, (8,)).cuda() | |
| loss_fn = lambda out: torch.nn.functional.cross_entropy(out, tgt) | |
| fwd = lambda model: loss_fn(model(inp[0].to(next(model.parameters()).dtype))) | |
| return m, fwd | |
| from models import GPT, SIZES | |
| c = SIZES[name] | |
| m = GPT(c) | |
| ix = torch.randint(0, c.vocab_size, (4, 512)).cuda() | |
| tg = torch.randint(0, c.vocab_size, (4, 512)).cuda() | |
| def fwd(model): | |
| _, loss = model(ix, tg) | |
| return loss | |
| return m, fwd | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--variant", required=True, | |
| choices=["ref", "flash", "flash_gr", "split_only", "quant_only"]) | |
| ap.add_argument("--model", required=True) | |
| args = ap.parse_args() | |
| torch.manual_seed(0) | |
| dev = torch.device("cuda") | |
| model, fwd = build_model(args.model) | |
| n_params = sum(p.numel() for p in model.parameters()) | |
| handle = None | |
| if args.variant in ("flash", "flash_gr", "split_only"): | |
| from flashoptim import FlashAdamW, cast_model, enable_gradient_release | |
| model = model.to(dev) | |
| cast_model(model, dtype=torch.bfloat16) | |
| else: | |
| model = model.to(dev) # fp32 | |
| gc.collect(); torch.cuda.empty_cache(); torch.cuda.synchronize() | |
| bytes_params = torch.cuda.memory_allocated() | |
| if args.variant == "ref": | |
| opt = torch.optim.AdamW(model.parameters(), lr=1e-4, betas=(0.9, 0.95), | |
| weight_decay=0.1) | |
| elif args.variant in ("flash", "flash_gr"): | |
| opt = FlashAdamW(model.parameters(), lr=1e-4, betas=(0.9, 0.95), | |
| weight_decay=0.1, master_weight_bits=24, quantize=True) | |
| elif args.variant == "split_only": | |
| opt = FlashAdamW(model.parameters(), lr=1e-4, betas=(0.9, 0.95), | |
| weight_decay=0.1, master_weight_bits=24, quantize=False) | |
| elif args.variant == "quant_only": | |
| from flashoptim import FlashAdamW # fp32 params | |
| opt = FlashAdamW(model.parameters(), lr=1e-4, betas=(0.9, 0.95), | |
| weight_decay=0.1, master_weight_bits=None, quantize=True) | |
| if args.variant == "flash_gr": | |
| handle = enable_gradient_release(model, opt) | |
| use_autocast = args.variant in ("ref", "quant_only") | |
| def one_iter(): | |
| with torch.autocast("cuda", dtype=torch.bfloat16, enabled=use_autocast): | |
| loss = fwd(model) | |
| loss.backward() | |
| opt.step() | |
| opt.zero_grad(set_to_none=True) | |
| return float(loss.detach()) | |
| # warmup: materialize grads + optimizer states + JIT kernels (3 iters) | |
| losses = [one_iter() for _ in range(3)] | |
| torch.cuda.synchronize() | |
| # grads freed by zero_grad(set_to_none) -> allocated == params + opt states | |
| gc.collect(); torch.cuda.empty_cache(); torch.cuda.synchronize() | |
| bytes_params_plus_state = torch.cuda.memory_allocated() | |
| bytes_state = bytes_params_plus_state - bytes_params | |
| # grads: measure right after a fresh backward, before step | |
| with torch.autocast("cuda", dtype=torch.bfloat16, enabled=use_autocast): | |
| loss = fwd(model) | |
| loss.backward() | |
| del loss | |
| gc.collect(); torch.cuda.synchronize() | |
| if args.variant == "flash_gr": | |
| bytes_grads = 0 # released eagerly during backward | |
| else: | |
| bytes_grads = torch.cuda.memory_allocated() - bytes_params_plus_state | |
| opt.step(); opt.zero_grad(set_to_none=True) | |
| # steady-state peak over one full iteration | |
| torch.cuda.reset_peak_memory_stats() | |
| losses.append(one_iter()) | |
| torch.cuda.synchronize() | |
| peak = torch.cuda.max_memory_allocated() | |
| if handle is not None: | |
| handle.remove() | |
| print(json.dumps(dict( | |
| variant=args.variant, model=args.model, n_params=n_params, | |
| bytes_params=bytes_params, bytes_state=bytes_state, | |
| bytes_grads=bytes_grads, peak_steady=peak, | |
| bpp_params=bytes_params / n_params, bpp_state=bytes_state / n_params, | |
| bpp_grads=bytes_grads / n_params, | |
| bpp_params_state_grads=(bytes_params + bytes_state + bytes_grads) / n_params, | |
| losses=[round(x, 4) for x in losses]))) | |
| sys.stdout.flush() | |
| if __name__ == "__main__": | |
| main() | |
Xet Storage Details
- Size:
- 5.16 kB
- Xet hash:
- fad2bfab51e294228114376381e73612630edb3d88d9fa16164d801735b94f72
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.