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
File size: 5,053 Bytes
fbfb7a1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 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)
|