Text Generation
Transformers
Safetensors
Vietnamese
sai
custom-code
vietnamese
causal-lm
custom_code
Instructions to use thongbuind/SAI_35M with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use thongbuind/SAI_35M with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="thongbuind/SAI_35M", trust_remote_code=True)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("thongbuind/SAI_35M", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use thongbuind/SAI_35M with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "thongbuind/SAI_35M" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "thongbuind/SAI_35M", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/thongbuind/SAI_35M
- SGLang
How to use thongbuind/SAI_35M 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 "thongbuind/SAI_35M" \ --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": "thongbuind/SAI_35M", "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 "thongbuind/SAI_35M" \ --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": "thongbuind/SAI_35M", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use thongbuind/SAI_35M with Docker Model Runner:
docker model run hf.co/thongbuind/SAI_35M
| import torch | |
| import torch.nn as nn | |
| from .generate import generate | |
| from .DecoderBlock import DecoderBlock | |
| from .RotaryPositionalEmbedding import RotaryPositionalEmbedding | |
| class TransformerModel(nn.Module): | |
| def __init__(self, vocab_size: int, d_model: int, num_heads: int, num_kv_heads: int, num_layers: int, ff_dim: int, max_seq_len: int, dropout: float, pad_token_id: int = 0): | |
| super().__init__() | |
| self.d_model = d_model | |
| self.num_heads = num_heads | |
| self.num_kv_heads = num_kv_heads | |
| self.num_layers = num_layers | |
| self.pad_token_id = pad_token_id | |
| self.max_seq_len = max_seq_len | |
| self.embed = nn.Embedding(vocab_size, d_model) | |
| d_k = d_model // num_heads | |
| self.rope = RotaryPositionalEmbedding(d_k, max_seq_len) | |
| self.blocks = nn.ModuleList([ | |
| DecoderBlock(d_model, num_heads, num_kv_heads, ff_dim, dropout) | |
| for _ in range(num_layers) | |
| ]) | |
| self.norm = nn.RMSNorm(d_model, eps=1e-6) | |
| self.lm_head = nn.Linear(d_model, vocab_size, bias=False) | |
| self.lm_head.weight = self.embed.weight | |
| causal = torch.triu( | |
| torch.full((max_seq_len, max_seq_len), float('-inf')), diagonal=1 | |
| ) | |
| self.register_buffer("causal_mask", causal, persistent=False) | |
| self._init_weights() | |
| def _init_weights(self): | |
| std = self.d_model ** -0.5 | |
| nn.init.normal_(self.embed.weight, mean=0.0, std=std) | |
| for module in self.modules(): | |
| if isinstance(module, nn.Linear): | |
| nn.init.normal_(module.weight, mean=0.0, std=std) | |
| if module.bias is not None: | |
| nn.init.zeros_(module.bias) | |
| def _build_attn_mask(self, T: int, pad_mask, device): | |
| attn_mask = self.causal_mask[:T, :T][None, None, :, :] | |
| if pad_mask is not None: | |
| pad = torch.zeros(pad_mask.shape[0], 1, 1, T, device=device) | |
| pad.masked_fill_(~pad_mask[:, None, None, :], float('-inf')) | |
| attn_mask = attn_mask + pad | |
| return attn_mask | |
| def forward_features(self, input_ids: torch.Tensor, attention_mask=None, has_padding: bool = True) -> torch.Tensor: | |
| """Giống forward() nhưng DỪNG TRƯỚC lm_head — dùng cho training loss chunked | |
| (tránh vật lý hóa logits full (B*T, vocab_size)).""" | |
| pad_mask = attention_mask.bool() if attention_mask is not None \ | |
| else (input_ids != self.pad_token_id) | |
| B, T = input_ids.shape | |
| x = self.embed(input_ids) | |
| pos = torch.arange(T, device=input_ids.device) | |
| cos, sin = self.rope.get_cos_sin(pos) | |
| # Chỉ build mask (và cộng pad-bias) khi batch này thực sự có token PAD. | |
| # Nếu không có PAD, causal mask thuần == causal+pad mask về mặt toán học | |
| # (pad-bias toàn số 0) -> bỏ qua an toàn, không đổi kết quả. | |
| # has_padding được tính sẵn trên CPU trong collate_fn nên không tốn sync GPU ở đây. | |
| attn_mask = self._build_attn_mask(T, pad_mask, x.device) if has_padding else None | |
| for block in self.blocks: | |
| x = block(x, cos, sin, attn_mask) | |
| return self.norm(x) # (B, T, d_model) — CHƯA qua lm_head | |
| def forward(self, input_ids: torch.Tensor, attention_mask=None, has_padding: bool = True) -> torch.Tensor: | |
| x = self.forward_features(input_ids, attention_mask, has_padding) | |
| return self.lm_head(x) | |
| def init_cache(self, batch_size: int, max_gen_len: int, device: torch.device): | |
| d_k = self.d_model // self.num_heads | |
| return [ | |
| [ | |
| torch.empty(batch_size, self.num_kv_heads, max_gen_len, d_k, device=device), | |
| torch.empty(batch_size, self.num_kv_heads, max_gen_len, d_k, device=device), | |
| ] | |
| for _ in self.blocks | |
| ] | |
| def prefill(self, input_ids: torch.Tensor, kv_cache=None): | |
| B, T = input_ids.shape | |
| x = self.embed(input_ids) | |
| pos = torch.arange(T, device=input_ids.device) | |
| cos, sin = self.rope.get_cos_sin(pos) | |
| new_cache = [] | |
| for i, block in enumerate(self.blocks): | |
| x, kv = block.prefill(x, cos, sin) | |
| if kv_cache is not None: | |
| kv_cache[i][0][:B, :, :T, :] = kv[0] | |
| kv_cache[i][1][:B, :, :T, :] = kv[1] | |
| new_cache.append(kv_cache[i]) | |
| else: | |
| new_cache.append(kv) | |
| logits = self.lm_head(self.norm(x))[:, -1, :] | |
| return logits, new_cache | |
| def decode_step(self, token_ids: torch.Tensor, kv_cache, cache_len: int): | |
| token_ids = token_ids.view(-1, 1) | |
| x = self.embed(token_ids) | |
| pos = torch.arange(cache_len, cache_len + 1, device=token_ids.device) | |
| cos, sin = self.rope.get_cos_sin(pos) | |
| for block, kv in zip(self.blocks, kv_cache): | |
| x = block.forward_with_cache(x, kv, cache_len, cos, sin) | |
| return self.lm_head(self.norm(x))[:, 0, :] | |
| def generate_response(self, user_input, tokenizer, **kwargs): | |
| return generate(self, user_input, tokenizer, **kwargs) | |