Text Generation
Transformers
Safetensors
edgerock
nvfp4
modelopt
quantized
custom_code
conversational
8-bit precision
Instructions to use hkust-aaron/EdgeRock-4B-NVFP4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use hkust-aaron/EdgeRock-4B-NVFP4 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="hkust-aaron/EdgeRock-4B-NVFP4", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("hkust-aaron/EdgeRock-4B-NVFP4", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use hkust-aaron/EdgeRock-4B-NVFP4 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "hkust-aaron/EdgeRock-4B-NVFP4" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hkust-aaron/EdgeRock-4B-NVFP4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/hkust-aaron/EdgeRock-4B-NVFP4
- SGLang
How to use hkust-aaron/EdgeRock-4B-NVFP4 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "hkust-aaron/EdgeRock-4B-NVFP4" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hkust-aaron/EdgeRock-4B-NVFP4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "hkust-aaron/EdgeRock-4B-NVFP4" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "hkust-aaron/EdgeRock-4B-NVFP4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use hkust-aaron/EdgeRock-4B-NVFP4 with Docker Model Runner:
docker model run hf.co/hkust-aaron/EdgeRock-4B-NVFP4
Download quantize.py from hkust-aaron/EdgeRock-4B-NVFP4: direct link, hf CLI and curl.
- Browser
- Download file 5.05 kB
-
https://huggingface.co/hkust-aaron/EdgeRock-4B-NVFP4/resolve/main/quantize.py
- Command line
-
hf download hf://hkust-aaron/EdgeRock-4B-NVFP4/quantize.py
-
curl -L -o quantize.py https://huggingface.co/hkust-aaron/EdgeRock-4B-NVFP4/resolve/main/quantize.py
5.05 kB
| import argparse | |
| import copy | |
| import json | |
| import shutil | |
| import time | |
| from pathlib import Path | |
| import modelopt.torch.quantization as mtq | |
| import torch | |
| from modelopt.torch.export import export_hf_checkpoint | |
| from safetensors import safe_open | |
| from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('--source', required=True) | |
| parser.add_argument('--output', required=True) | |
| args = parser.parse_args() | |
| source, output = Path(args.source), Path(args.output) | |
| output.mkdir(parents=True, exist_ok=False) | |
| torch.set_num_threads(4) | |
| torch.manual_seed(20261020) | |
| config = AutoConfig.from_pretrained(source, trust_remote_code=True, local_files_only=True) | |
| config.backend = 'torch' | |
| config.prefill_chunk_size = 512 | |
| model = AutoModelForCausalLM.from_pretrained( | |
| source, config=config, trust_remote_code=True, local_files_only=True, | |
| dtype=torch.bfloat16, device_map={'': 0}, attn_implementation='sdpa', | |
| ).eval().requires_grad_(False) | |
| tokenizer = AutoTokenizer.from_pretrained(source, trust_remote_code=True, local_files_only=True) | |
| tokenizer.chat_template = (Path(__file__).parent/'chat_template.jinja').read_text() | |
| model.generation_config.eos_token_id = [248046, 248044] | |
| model.generation_config.pad_token_id = tokenizer.pad_token_id | |
| modules = {} | |
| recipe = copy.deepcopy(mtq.W4A16_NVFP4_CFG) | |
| for name, module in model.named_modules(): | |
| if not isinstance(module, torch.nn.Linear): | |
| continue | |
| if name != 'lm_head' and min(module.weight.shape) >= 128 and '.admission_' not in name: | |
| assert module.in_features % 16 == 0 and module.out_features % 16 == 0, name | |
| modules[name] = list(module.weight.shape) | |
| else: | |
| recipe['quant_cfg'].append({'quantizer_name': name+'.*', 'enable': False}) | |
| assert modules | |
| probe = tokenizer('The sum of 17 and 23 is', return_tensors='pt').to('cuda') | |
| started = time.perf_counter() | |
| print(json.dumps({'stage': 'quantizing', 'modules': len(modules), 'format': 'W4A16_NVFP4'}), flush=True) | |
| with torch.inference_mode(): | |
| mtq.quantize(model, recipe, forward_loop=lambda current: current(**probe, use_cache=False, logits_to_keep=1)) | |
| quantized_probe = model(**probe, use_cache=False, logits_to_keep=1).logits.float().cpu() | |
| assert torch.isfinite(quantized_probe).all() | |
| torch.save(quantized_probe, output.parent/'quantizer_probe.pt') | |
| print(json.dumps({'stage': 'exporting'}), flush=True) | |
| export_hf_checkpoint(model, export_dir=output, save_modelopt_state=False, max_shard_size='4GB') | |
| tokenizer.save_pretrained(output) | |
| for name in ('configuration_edgerock.py', 'modeling_edgerock.py', 'LICENSE', 'LICENSE-CODE', 'NOTICE'): | |
| shutil.copy2(source/name, output/name) | |
| for name in ('load_nvfp4.py', 'quantize.py'): | |
| shutil.copy2(Path(__file__).parent/name, output/name) | |
| shutil.copy2(Path(__file__).parent/'chat_template.jinja', output/'chat_template.jinja') | |
| hf_config = json.loads((output/'hf_quant_config.json').read_text()) | |
| assert hf_config['quantization']['quant_algo'] == 'W4A16_NVFP4', hf_config | |
| manifest = { | |
| 'format': 'NVFP4', 'recipe': 'W4A16_NVFP4', 'weight_encoding': 'E2M1, two values per byte, low nibble first', | |
| 'block_size': 16, 'block_scale_dtype': 'float8_e4m3fn', 'global_scale_dtype': 'float32', | |
| 'activation_dtype': 'bfloat16', 'scale_layout': 'row-major', 'modules': modules, | |
| 'embedding_and_lm_head': 'unquantized, tied', | |
| 'preserved': ['admission networks', 'small recurrent gates', 'normalization', 'history capacities and update rules'], | |
| } | |
| (output/'nvfp4_config.json').write_text(json.dumps(manifest, indent=2)+'\n') | |
| packed = {} | |
| for shard in sorted(output.glob('model*.safetensors')): | |
| with safe_open(shard, framework='pt', device='cpu') as handle: | |
| for name, shape in modules.items(): | |
| if name+'.weight' not in handle.keys(): | |
| continue | |
| weight = handle.get_tensor(name+'.weight') | |
| scale = handle.get_tensor(name+'.weight_scale') | |
| global_scale = handle.get_tensor(name+'.weight_scale_2') | |
| assert weight.dtype == torch.uint8 and list(weight.shape) == [shape[0], shape[1]//2], name | |
| assert scale.dtype == torch.float8_e4m3fn and scale.numel() == shape[0]*shape[1]//16, name | |
| assert global_scale.dtype == torch.float32 and global_scale.numel() == 1, name | |
| assert torch.isfinite(scale.float()).all() and global_scale.item() > 0, name | |
| packed[name] = {'shape': shape, 'weight_bytes': weight.numel(), 'scale_bytes': scale.numel()+4} | |
| assert set(packed) == set(modules) | |
| receipt = { | |
| 'format': 'W4A16_NVFP4', 'quantized_modules': len(packed), 'modules': packed, | |
| 'conversion_seconds': time.perf_counter()-started, | |
| 'weight_bytes': sum(path.stat().st_size for path in output.glob('model*.safetensors')), | |
| 'gpu': torch.cuda.get_device_name(0), 'modelopt_version': '0.47.0', | |
| } | |
| (output/'conversion.json').write_text(json.dumps(receipt, indent=2)+'\n') | |
| print(json.dumps({'stage': 'conversion_complete', 'modules': len(packed), 'weight_bytes': receipt['weight_bytes']}), flush=True) | |