Instructions to use himalaya-ai/himalayagpt-0.5b-it with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use himalaya-ai/himalayagpt-0.5b-it with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="himalaya-ai/himalayagpt-0.5b-it", trust_remote_code=True)# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("himalaya-ai/himalayagpt-0.5b-it", trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained("himalaya-ai/himalayagpt-0.5b-it", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use himalaya-ai/himalayagpt-0.5b-it with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "himalaya-ai/himalayagpt-0.5b-it" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "himalaya-ai/himalayagpt-0.5b-it", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/himalaya-ai/himalayagpt-0.5b-it
- SGLang
How to use himalaya-ai/himalayagpt-0.5b-it 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 "himalaya-ai/himalayagpt-0.5b-it" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "himalaya-ai/himalayagpt-0.5b-it", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'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 "himalaya-ai/himalayagpt-0.5b-it" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "himalaya-ai/himalayagpt-0.5b-it", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use himalaya-ai/himalayagpt-0.5b-it with Docker Model Runner:
docker model run hf.co/himalaya-ai/himalayagpt-0.5b-it
Re-export SFT 49164 with HF parity fixes
Browse files- README.md +3 -3
- modeling_nanochat.py +82 -43
README.md
CHANGED
|
@@ -6,7 +6,7 @@ tags:
|
|
| 6 |
- trust-remote-code
|
| 7 |
---
|
| 8 |
|
| 9 |
-
#
|
| 10 |
|
| 11 |
Exported from nanochat checkpoints with custom `transformers` remote code.
|
| 12 |
|
|
@@ -16,12 +16,12 @@ Exported from nanochat checkpoints with custom `transformers` remote code.
|
|
| 16 |
from transformers import AutoTokenizer, AutoModelForCausalLM
|
| 17 |
import torch
|
| 18 |
|
| 19 |
-
repo = "
|
| 20 |
tok = AutoTokenizer.from_pretrained(repo, trust_remote_code=True)
|
| 21 |
model = AutoModelForCausalLM.from_pretrained(
|
| 22 |
repo,
|
| 23 |
trust_remote_code=True,
|
| 24 |
-
torch_dtype=
|
| 25 |
device_map="auto" if torch.cuda.is_available() else None,
|
| 26 |
)
|
| 27 |
|
|
|
|
| 6 |
- trust-remote-code
|
| 7 |
---
|
| 8 |
|
| 9 |
+
# local/nanochat-export
|
| 10 |
|
| 11 |
Exported from nanochat checkpoints with custom `transformers` remote code.
|
| 12 |
|
|
|
|
| 16 |
from transformers import AutoTokenizer, AutoModelForCausalLM
|
| 17 |
import torch
|
| 18 |
|
| 19 |
+
repo = "local/nanochat-export"
|
| 20 |
tok = AutoTokenizer.from_pretrained(repo, trust_remote_code=True)
|
| 21 |
model = AutoModelForCausalLM.from_pretrained(
|
| 22 |
repo,
|
| 23 |
trust_remote_code=True,
|
| 24 |
+
torch_dtype="auto",
|
| 25 |
device_map="auto" if torch.cuda.is_available() else None,
|
| 26 |
)
|
| 27 |
|
modeling_nanochat.py
CHANGED
|
@@ -11,6 +11,17 @@ def _norm(x):
|
|
| 11 |
return F.rms_norm(x, (x.size(-1),))
|
| 12 |
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
class Linear(nn.Linear):
|
| 15 |
def forward(self, x):
|
| 16 |
return F.linear(x, self.weight.to(dtype=x.dtype))
|
|
@@ -28,6 +39,47 @@ def _apply_rotary(x, cos, sin):
|
|
| 28 |
return torch.cat([y1, y2], dim=-1)
|
| 29 |
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
class NanochatAttention(nn.Module):
|
| 32 |
def __init__(self, config, layer_idx):
|
| 33 |
super().__init__()
|
|
@@ -43,15 +95,7 @@ class NanochatAttention(nn.Module):
|
|
| 43 |
self.ve_gate_channels = 12
|
| 44 |
self.ve_gate = Linear(self.ve_gate_channels, self.n_kv_head, bias=False) if _has_ve(layer_idx, config.n_layer) else None
|
| 45 |
|
| 46 |
-
def
|
| 47 |
-
if left_window < 0 or left_window >= t:
|
| 48 |
-
return None
|
| 49 |
-
i = torch.arange(t, device=device)
|
| 50 |
-
causal = i[:, None] >= i[None, :]
|
| 51 |
-
local = (i[:, None] - i[None, :]) < left_window
|
| 52 |
-
return causal & local
|
| 53 |
-
|
| 54 |
-
def forward(self, x, ve, cos_sin, left_window):
|
| 55 |
bsz, seqlen, _ = x.size()
|
| 56 |
q = self.c_q(x).view(bsz, seqlen, self.n_head, self.head_dim)
|
| 57 |
k = self.c_k(x).view(bsz, seqlen, self.n_kv_head, self.head_dim)
|
|
@@ -68,24 +112,8 @@ class NanochatAttention(nn.Module):
|
|
| 68 |
q = 1.2 * _norm(q)
|
| 69 |
k = 1.2 * _norm(k)
|
| 70 |
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
v = v.transpose(1, 2)
|
| 74 |
-
if self.n_kv_head != self.n_head:
|
| 75 |
-
rep = self.n_head // self.n_kv_head
|
| 76 |
-
k = k.repeat_interleave(rep, dim=1)
|
| 77 |
-
v = v.repeat_interleave(rep, dim=1)
|
| 78 |
-
|
| 79 |
-
attn_mask = self._layer_mask(seqlen, left_window, x.device)
|
| 80 |
-
y = F.scaled_dot_product_attention(
|
| 81 |
-
q,
|
| 82 |
-
k,
|
| 83 |
-
v,
|
| 84 |
-
attn_mask=attn_mask,
|
| 85 |
-
dropout_p=0.0,
|
| 86 |
-
is_causal=(attn_mask is None),
|
| 87 |
-
)
|
| 88 |
-
y = y.transpose(1, 2).contiguous().view(bsz, seqlen, -1)
|
| 89 |
return self.c_proj(y)
|
| 90 |
|
| 91 |
|
|
@@ -105,8 +133,8 @@ class NanochatBlock(nn.Module):
|
|
| 105 |
self.attn = NanochatAttention(config, layer_idx)
|
| 106 |
self.mlp = NanochatMLP(config)
|
| 107 |
|
| 108 |
-
def forward(self, x, ve, cos_sin,
|
| 109 |
-
x = x + self.attn(_norm(x), ve, cos_sin,
|
| 110 |
x = x + self.mlp(_norm(x))
|
| 111 |
return x
|
| 112 |
|
|
@@ -142,17 +170,22 @@ class NanochatBackbone(nn.Module):
|
|
| 142 |
self.register_buffer("sin", torch.empty(1), persistent=False)
|
| 143 |
self._refresh_rotary()
|
| 144 |
|
| 145 |
-
def
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
t = torch.arange(self.rotary_seq_len, dtype=torch.float32, device=device)
|
| 151 |
-
ch = torch.arange(0, head_dim, 2, dtype=torch.float32, device=device)
|
| 152 |
-
inv = 1.0 / (100000 ** (ch / head_dim))
|
| 153 |
-
freqs = torch.outer(t, inv)
|
| 154 |
cos = freqs.cos()[None, :, None, :].to(dtype=dtype)
|
| 155 |
sin = freqs.sin()[None, :, None, :].to(dtype=dtype)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
self.cos = cos
|
| 157 |
self.sin = sin
|
| 158 |
|
|
@@ -170,11 +203,19 @@ class NanochatBackbone(nn.Module):
|
|
| 170 |
|
| 171 |
def forward(self, input_ids):
|
| 172 |
bsz, seqlen = input_ids.shape
|
| 173 |
-
|
| 174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
cos_sin = self.cos[:, :seqlen], self.sin[:, :seqlen]
|
| 176 |
|
| 177 |
x = self.transformer["wte"](input_ids)
|
|
|
|
| 178 |
x = _norm(x)
|
| 179 |
if seqlen > 1:
|
| 180 |
gate = self.smear_lambda.to(x.dtype) * torch.sigmoid(self.smear_gate(x[:, 1:, :24]))
|
|
@@ -186,7 +227,7 @@ class NanochatBackbone(nn.Module):
|
|
| 186 |
for i, block in enumerate(self.transformer["h"]):
|
| 187 |
x = self.resid_lambdas[i] * x + self.x0_lambdas[i] * x0
|
| 188 |
ve = self.value_embeds[str(i)](input_ids).to(x.dtype) if str(i) in self.value_embeds else None
|
| 189 |
-
x = block(x, ve, cos_sin, self.window_sizes[i]
|
| 190 |
if i == backout_layer:
|
| 191 |
x_backout = x
|
| 192 |
|
|
@@ -213,8 +254,6 @@ class NanochatForCausalLM(PreTrainedModel):
|
|
| 213 |
def all_tied_weights_keys(self):
|
| 214 |
# Compatibility shim for some transformers/accelerate versions that
|
| 215 |
# access `model.all_tied_weights_keys` during device_map inference.
|
| 216 |
-
# Newer codepaths call `.keys()` on this object, so expose a dict-like
|
| 217 |
-
# mapping regardless of the underlying list/tuple representation.
|
| 218 |
return {k: None for k in getattr(self, "_tied_weights_keys", [])}
|
| 219 |
|
| 220 |
def get_input_embeddings(self):
|
|
|
|
| 11 |
return F.rms_norm(x, (x.size(-1),))
|
| 12 |
|
| 13 |
|
| 14 |
+
def _detect_compute_dtype(device):
|
| 15 |
+
if device.type == "cuda":
|
| 16 |
+
idx = device.index
|
| 17 |
+
if idx is None:
|
| 18 |
+
idx = torch.cuda.current_device()
|
| 19 |
+
major, minor = torch.cuda.get_device_capability(idx)
|
| 20 |
+
if (major, minor) >= (8, 0):
|
| 21 |
+
return torch.bfloat16
|
| 22 |
+
return torch.float32
|
| 23 |
+
|
| 24 |
+
|
| 25 |
class Linear(nn.Linear):
|
| 26 |
def forward(self, x):
|
| 27 |
return F.linear(x, self.weight.to(dtype=x.dtype))
|
|
|
|
| 39 |
return torch.cat([y1, y2], dim=-1)
|
| 40 |
|
| 41 |
|
| 42 |
+
def _sdpa_attention(q, k, v, window_size, enable_gqa):
|
| 43 |
+
# q/k/v are (B, H, T, D)
|
| 44 |
+
t_q = q.size(2)
|
| 45 |
+
t_k = k.size(2)
|
| 46 |
+
left_window = window_size[0]
|
| 47 |
+
|
| 48 |
+
# Full causal attention when the window covers full context.
|
| 49 |
+
if (left_window < 0 or left_window >= t_q) and t_q == t_k:
|
| 50 |
+
return F.scaled_dot_product_attention(q, k, v, is_causal=True, enable_gqa=enable_gqa)
|
| 51 |
+
|
| 52 |
+
# Single-token decode path.
|
| 53 |
+
if t_q == 1:
|
| 54 |
+
if left_window >= 0 and left_window < t_k:
|
| 55 |
+
start = max(0, t_k - (left_window + 1))
|
| 56 |
+
k = k[:, :, start:, :]
|
| 57 |
+
v = v[:, :, start:, :]
|
| 58 |
+
return F.scaled_dot_product_attention(q, k, v, is_causal=False, enable_gqa=enable_gqa)
|
| 59 |
+
|
| 60 |
+
# Build explicit causal (+ optional sliding-window) mask.
|
| 61 |
+
device = q.device
|
| 62 |
+
row_idx = (t_k - t_q) + torch.arange(t_q, device=device).unsqueeze(1)
|
| 63 |
+
col_idx = torch.arange(t_k, device=device).unsqueeze(0)
|
| 64 |
+
mask = col_idx <= row_idx
|
| 65 |
+
if left_window >= 0 and left_window < t_k:
|
| 66 |
+
mask = mask & ((row_idx - col_idx) <= left_window)
|
| 67 |
+
|
| 68 |
+
return F.scaled_dot_product_attention(q, k, v, attn_mask=mask, enable_gqa=enable_gqa)
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def _flash_attn_func(q, k, v, causal=False, window_size=(-1, -1)):
|
| 72 |
+
if not causal:
|
| 73 |
+
raise NotImplementedError("Nanochat HF export currently supports only causal attention")
|
| 74 |
+
# SDPA fallback mirroring nanochat.flash_attention semantics.
|
| 75 |
+
q = q.transpose(1, 2)
|
| 76 |
+
k = k.transpose(1, 2)
|
| 77 |
+
v = v.transpose(1, 2)
|
| 78 |
+
enable_gqa = q.size(1) != k.size(1)
|
| 79 |
+
y = _sdpa_attention(q, k, v, window_size=window_size, enable_gqa=enable_gqa)
|
| 80 |
+
return y.transpose(1, 2)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
class NanochatAttention(nn.Module):
|
| 84 |
def __init__(self, config, layer_idx):
|
| 85 |
super().__init__()
|
|
|
|
| 95 |
self.ve_gate_channels = 12
|
| 96 |
self.ve_gate = Linear(self.ve_gate_channels, self.n_kv_head, bias=False) if _has_ve(layer_idx, config.n_layer) else None
|
| 97 |
|
| 98 |
+
def forward(self, x, ve, cos_sin, window_size):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
bsz, seqlen, _ = x.size()
|
| 100 |
q = self.c_q(x).view(bsz, seqlen, self.n_head, self.head_dim)
|
| 101 |
k = self.c_k(x).view(bsz, seqlen, self.n_kv_head, self.head_dim)
|
|
|
|
| 112 |
q = 1.2 * _norm(q)
|
| 113 |
k = 1.2 * _norm(k)
|
| 114 |
|
| 115 |
+
y = _flash_attn_func(q, k, v, causal=True, window_size=window_size)
|
| 116 |
+
y = y.contiguous().view(bsz, seqlen, -1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
return self.c_proj(y)
|
| 118 |
|
| 119 |
|
|
|
|
| 133 |
self.attn = NanochatAttention(config, layer_idx)
|
| 134 |
self.mlp = NanochatMLP(config)
|
| 135 |
|
| 136 |
+
def forward(self, x, ve, cos_sin, window_size):
|
| 137 |
+
x = x + self.attn(_norm(x), ve, cos_sin, window_size)
|
| 138 |
x = x + self.mlp(_norm(x))
|
| 139 |
return x
|
| 140 |
|
|
|
|
| 170 |
self.register_buffer("sin", torch.empty(1), persistent=False)
|
| 171 |
self._refresh_rotary()
|
| 172 |
|
| 173 |
+
def _precompute_rotary_embeddings(self, seq_len, head_dim, device, dtype):
|
| 174 |
+
channel_range = torch.arange(0, head_dim, 2, dtype=torch.float32, device=device)
|
| 175 |
+
inv_freq = 1.0 / (100000 ** (channel_range / head_dim))
|
| 176 |
+
t = torch.arange(seq_len, dtype=torch.float32, device=device)
|
| 177 |
+
freqs = torch.outer(t, inv_freq)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
cos = freqs.cos()[None, :, None, :].to(dtype=dtype)
|
| 179 |
sin = freqs.sin()[None, :, None, :].to(dtype=dtype)
|
| 180 |
+
return cos, sin
|
| 181 |
+
|
| 182 |
+
def _refresh_rotary(self, device=None, dtype=None):
|
| 183 |
+
head_dim = self.config.n_embd // self.config.n_head
|
| 184 |
+
if device is None:
|
| 185 |
+
device = self.transformer.wte.weight.device
|
| 186 |
+
if dtype is None:
|
| 187 |
+
dtype = self.transformer.wte.weight.dtype
|
| 188 |
+
cos, sin = self._precompute_rotary_embeddings(self.rotary_seq_len, head_dim, device=device, dtype=dtype)
|
| 189 |
self.cos = cos
|
| 190 |
self.sin = sin
|
| 191 |
|
|
|
|
| 203 |
|
| 204 |
def forward(self, input_ids):
|
| 205 |
bsz, seqlen = input_ids.shape
|
| 206 |
+
compute_dtype = _detect_compute_dtype(input_ids.device)
|
| 207 |
+
if self.cos.device != input_ids.device or self.cos.dtype != compute_dtype:
|
| 208 |
+
self._refresh_rotary(device=input_ids.device, dtype=compute_dtype)
|
| 209 |
+
|
| 210 |
+
if seqlen > self.cos.size(1):
|
| 211 |
+
raise ValueError(
|
| 212 |
+
f"Sequence length {seqlen} exceeds rotary cache length {self.cos.size(1)}. "
|
| 213 |
+
"Re-export with larger sequence_len if needed."
|
| 214 |
+
)
|
| 215 |
cos_sin = self.cos[:, :seqlen], self.sin[:, :seqlen]
|
| 216 |
|
| 217 |
x = self.transformer["wte"](input_ids)
|
| 218 |
+
x = x.to(compute_dtype)
|
| 219 |
x = _norm(x)
|
| 220 |
if seqlen > 1:
|
| 221 |
gate = self.smear_lambda.to(x.dtype) * torch.sigmoid(self.smear_gate(x[:, 1:, :24]))
|
|
|
|
| 227 |
for i, block in enumerate(self.transformer["h"]):
|
| 228 |
x = self.resid_lambdas[i] * x + self.x0_lambdas[i] * x0
|
| 229 |
ve = self.value_embeds[str(i)](input_ids).to(x.dtype) if str(i) in self.value_embeds else None
|
| 230 |
+
x = block(x, ve, cos_sin, self.window_sizes[i])
|
| 231 |
if i == backout_layer:
|
| 232 |
x_backout = x
|
| 233 |
|
|
|
|
| 254 |
def all_tied_weights_keys(self):
|
| 255 |
# Compatibility shim for some transformers/accelerate versions that
|
| 256 |
# access `model.all_tied_weights_keys` during device_map inference.
|
|
|
|
|
|
|
| 257 |
return {k: None for k in getattr(self, "_tied_weights_keys", [])}
|
| 258 |
|
| 259 |
def get_input_embeddings(self):
|