Instructions to use EBLANSoft/eblangpt-2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use EBLANSoft/eblangpt-2 with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf EBLANSoft/eblangpt-2 # Run inference directly in the terminal: llama cli -hf EBLANSoft/eblangpt-2
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf EBLANSoft/eblangpt-2 # Run inference directly in the terminal: llama cli -hf EBLANSoft/eblangpt-2
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf EBLANSoft/eblangpt-2 # Run inference directly in the terminal: ./llama-cli -hf EBLANSoft/eblangpt-2
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf EBLANSoft/eblangpt-2 # Run inference directly in the terminal: ./build/bin/llama-cli -hf EBLANSoft/eblangpt-2
Use Docker
docker model run hf.co/EBLANSoft/eblangpt-2
- LM Studio
- Jan
- vLLM
How to use EBLANSoft/eblangpt-2 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "EBLANSoft/eblangpt-2" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "EBLANSoft/eblangpt-2", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/EBLANSoft/eblangpt-2
- Ollama
How to use EBLANSoft/eblangpt-2 with Ollama:
ollama run hf.co/EBLANSoft/eblangpt-2
- Unsloth Studio
How to use EBLANSoft/eblangpt-2 with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for EBLANSoft/eblangpt-2 to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for EBLANSoft/eblangpt-2 to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for EBLANSoft/eblangpt-2 to start chatting
- Docker Model Runner
How to use EBLANSoft/eblangpt-2 with Docker Model Runner:
docker model run hf.co/EBLANSoft/eblangpt-2
- Lemonade
How to use EBLANSoft/eblangpt-2 with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull EBLANSoft/eblangpt-2
Run and chat with the model
lemonade run user.eblangpt-2-{{QUANT_TAG}}List all available models
lemonade list
- Atomic Chat
| """ | |
| tiny_llama.py — крошечная LLaMA для llama.cpp. | |
| Архитектура как у настоящей LLaMA: RMSNorm + RoPE + SwiGLU + causal attention. | |
| Байт-вокаб (256 токенов) чтоб не возиться со спм/бпе. | |
| Запуск: | |
| python tiny_llama.py train russian.txt eblangpt1984.gguf | |
| python tiny_llama.py test eblangpt1984.gguf # проверить что корректно читается | |
| После экспорта пробуй: | |
| llama-cli -m eblangpt1984.gguf -p "привет" -n 200 --temp 0.8 | |
| """ | |
| import sys | |
| import math | |
| import time | |
| import struct | |
| import numpy as np | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from gguf import GGUFWriter, TokenType | |
| # ===================== КОНФИГ ===================== | |
| VOCAB = 256 | |
| N_EMBD = 64 | |
| N_LAYERS = 2 | |
| N_HEADS = 4 | |
| HEAD_DIM = N_EMBD // N_HEADS # 16 | |
| N_FF = 128 | |
| CTX_LEN = 64 | |
| ROPE_THETA = 10000.0 | |
| RMS_EPS = 1e-5 | |
| ARCH = "llama" | |
| MODEL_NAME = "eblangpt1984" | |
| # ===================== МОДЕЛЬ ===================== | |
| class RMSNorm(nn.Module): | |
| def __init__(self, d, eps=RMS_EPS): | |
| super().__init__() | |
| self.weight = nn.Parameter(torch.ones(d)) | |
| self.eps = eps | |
| def forward(self, x): | |
| return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.weight | |
| def precompute_rope(seqlen, head_dim, theta=ROPE_THETA, device="cpu"): | |
| freqs = 1.0 / (theta ** (torch.arange(0, head_dim, 2, device=device).float() / head_dim)) | |
| t = torch.arange(seqlen, device=device).float() | |
| f = torch.outer(t, freqs) # [T, D/2] | |
| return torch.cos(f), torch.sin(f) # каждый [T, D/2] | |
| def apply_rope(x, cos, sin): | |
| # x: [B, H, T, D]. Используется "interleaved" схема — как в llama.cpp. | |
| T = x.size(-2) | |
| cos = cos[:T].unsqueeze(0).unsqueeze(0) | |
| sin = sin[:T].unsqueeze(0).unsqueeze(0) | |
| x1, x2 = x[..., 0::2], x[..., 1::2] | |
| y1 = x1 * cos - x2 * sin | |
| y2 = x1 * sin + x2 * cos | |
| return torch.stack((y1, y2), dim=-1).flatten(-2) | |
| class Block(nn.Module): | |
| def __init__(self): | |
| super().__init__() | |
| self.attn_norm = RMSNorm(N_EMBD) | |
| self.wq = nn.Linear(N_EMBD, N_EMBD, bias=False) | |
| self.wk = nn.Linear(N_EMBD, N_EMBD, bias=False) | |
| self.wv = nn.Linear(N_EMBD, N_EMBD, bias=False) | |
| self.wo = nn.Linear(N_EMBD, N_EMBD, bias=False) | |
| self.ffn_norm = RMSNorm(N_EMBD) | |
| self.w_gate = nn.Linear(N_EMBD, N_FF, bias=False) | |
| self.w_up = nn.Linear(N_EMBD, N_FF, bias=False) | |
| self.w_down = nn.Linear(N_FF, N_EMBD, bias=False) | |
| def forward(self, x, cos, sin, mask): | |
| B, T, D = x.shape | |
| h = self.attn_norm(x) | |
| q = self.wq(h).view(B, T, N_HEADS, HEAD_DIM).transpose(1, 2) | |
| k = self.wk(h).view(B, T, N_HEADS, HEAD_DIM).transpose(1, 2) | |
| v = self.wv(h).view(B, T, N_HEADS, HEAD_DIM).transpose(1, 2) | |
| q = apply_rope(q, cos, sin) | |
| k = apply_rope(k, cos, sin) | |
| att = (q @ k.transpose(-2, -1)) / math.sqrt(HEAD_DIM) | |
| att = att.masked_fill(mask[:T, :T], float("-inf")) | |
| att = F.softmax(att, dim=-1) | |
| out = (att @ v).transpose(1, 2).contiguous().view(B, T, D) | |
| x = x + self.wo(out) | |
| h = self.ffn_norm(x) | |
| x = x + self.w_down(F.silu(self.w_gate(h)) * self.w_up(h)) | |
| return x | |
| class TinyLlama(nn.Module): | |
| def __init__(self): | |
| super().__init__() | |
| self.embed = nn.Embedding(VOCAB, N_EMBD) | |
| self.blocks = nn.ModuleList([Block() for _ in range(N_LAYERS)]) | |
| self.norm = RMSNorm(N_EMBD) | |
| self.lm_head = nn.Linear(N_EMBD, VOCAB, bias=False) | |
| cos, sin = precompute_rope(CTX_LEN, HEAD_DIM) | |
| self.register_buffer("cos", cos, persistent=False) | |
| self.register_buffer("sin", sin, persistent=False) | |
| mask = torch.triu(torch.ones(CTX_LEN, CTX_LEN, dtype=torch.bool), diagonal=1) | |
| self.register_buffer("mask", mask, persistent=False) | |
| def forward(self, x): | |
| h = self.embed(x) | |
| for b in self.blocks: | |
| h = b(h, self.cos, self.sin, self.mask) | |
| return self.lm_head(self.norm(h)) | |
| # ===================== ОБУЧЕНИЕ ===================== | |
| def train_model(text_path, out_path, steps=3000, lr=3e-3, bs=16): | |
| with open(text_path, "rb") as f: | |
| data = f.read() | |
| print(f"текст: {len(data)} байт") | |
| ids = np.frombuffer(data, dtype=np.uint8).astype(np.int64) | |
| torch.manual_seed(42) | |
| model = TinyLlama() | |
| n_params = sum(p.numel() for p in model.parameters()) | |
| print(f"модель: {n_params:,} параметров") | |
| opt = torch.optim.AdamW(model.parameters(), lr=lr, weight_decay=0.01) | |
| def sample_batch(): | |
| idx = np.random.randint(0, len(ids) - CTX_LEN - 1, size=bs) | |
| x = np.stack([ids[i:i + CTX_LEN] for i in idx]) | |
| y = np.stack([ids[i + 1:i + CTX_LEN + 1] for i in idx]) | |
| return torch.from_numpy(x), torch.from_numpy(y) | |
| model.train() | |
| t0 = time.time() | |
| run = 0.0 | |
| for step in range(steps): | |
| x, y = sample_batch() | |
| logits = model(x) | |
| loss = F.cross_entropy(logits.view(-1, VOCAB), y.view(-1)) | |
| opt.zero_grad() | |
| loss.backward() | |
| torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) | |
| opt.step() | |
| run = 0.98 * run + 0.02 * loss.item() if step else loss.item() | |
| if step % 100 == 0 or step == steps - 1: | |
| dt = time.time() - t0 | |
| print(f" шаг {step:5d}/{steps} loss={run:.3f} [{dt:.1f}s]") | |
| export_gguf(model, out_path) | |
| # ===================== ЭКСПОРТ В GGUF (архитектура "llama") ===================== | |
| def export_gguf(model, out_path): | |
| print(f"экспорт в {out_path}...") | |
| w = GGUFWriter(out_path, ARCH) | |
| # --- метадата LLaMA --- | |
| w.add_name(MODEL_NAME) | |
| w.add_context_length(CTX_LEN) | |
| w.add_embedding_length(N_EMBD) | |
| w.add_block_count(N_LAYERS) | |
| w.add_feed_forward_length(N_FF) | |
| w.add_head_count(N_HEADS) | |
| w.add_head_count_kv(N_HEADS) # без GQA | |
| w.add_layer_norm_rms_eps(RMS_EPS) | |
| w.add_rope_dimension_count(HEAD_DIM) | |
| w.add_rope_freq_base(ROPE_THETA) | |
| w.add_file_type(0) # all F32 | |
| # --- байт-токенайзер --- | |
| tokens = [f"<0x{b:02X}>".encode("utf-8") for b in range(VOCAB)] | |
| scores = [-1000.0 + float(i) for i in range(VOCAB)] | |
| types = [TokenType.BYTE.value] * VOCAB | |
| w.add_tokenizer_model("llama") | |
| w.add_tokenizer_pre("default") | |
| w.add_token_list(tokens) | |
| w.add_token_scores(scores) | |
| w.add_token_types(types) | |
| w.add_bos_token_id(0) | |
| w.add_eos_token_id(0) | |
| w.add_unk_token_id(0) | |
| w.add_add_bos_token(False) | |
| w.add_add_eos_token(False) | |
| # --- тензоры --- | |
| sd = model.state_dict() | |
| def add(name, tensor): | |
| arr = tensor.detach().to(torch.float32).cpu().numpy() | |
| w.add_tensor(name, arr) | |
| add("token_embd.weight", sd["embed.weight"]) # [V, E] | |
| add("output_norm.weight", sd["norm.weight"]) # [E] | |
| add("output.weight", sd["lm_head.weight"]) # [V, E] | |
| for i in range(N_LAYERS): | |
| p = f"blocks.{i}" | |
| q = f"blk.{i}" | |
| add(f"{q}.attn_norm.weight", sd[f"{p}.attn_norm.weight"]) | |
| add(f"{q}.attn_q.weight", sd[f"{p}.wq.weight"]) | |
| add(f"{q}.attn_k.weight", sd[f"{p}.wk.weight"]) | |
| add(f"{q}.attn_v.weight", sd[f"{p}.wv.weight"]) | |
| add(f"{q}.attn_output.weight", sd[f"{p}.wo.weight"]) | |
| add(f"{q}.ffn_norm.weight", sd[f"{p}.ffn_norm.weight"]) | |
| add(f"{q}.ffn_gate.weight", sd[f"{p}.w_gate.weight"]) | |
| add(f"{q}.ffn_up.weight", sd[f"{p}.w_up.weight"]) | |
| add(f"{q}.ffn_down.weight", sd[f"{p}.w_down.weight"]) | |
| w.write_header_to_file() | |
| w.write_kv_data_to_file() | |
| w.write_tensors_to_file() | |
| w.close() | |
| print(f"готово: {out_path}") | |
| # ===================== ПРОВЕРКА ФАЙЛА ===================== | |
| def test_gguf(path): | |
| with open(path, "rb") as f: | |
| magic, ver = struct.unpack("<II", f.read(8)) | |
| tc, kv = struct.unpack("<QQ", f.read(16)) | |
| print(f"GGUF v{ver}, магия=0x{magic:08X}") | |
| print(f" тензоров: {tc}") | |
| print(f" метадата записей: {kv}") | |
| print(f" размер файла: {__import__('os').path.getsize(path)} байт") | |
| assert magic == 0x46554747, "битая магия" | |
| print("формат валидный ✓") | |
| # ===================== MAIN ===================== | |
| if __name__ == "__main__": | |
| if len(sys.argv) < 2: | |
| print(__doc__) | |
| sys.exit(1) | |
| cmd = sys.argv[1] | |
| if cmd == "train": | |
| text = sys.argv[2] if len(sys.argv) > 2 else "russian_mini.txt" | |
| out = sys.argv[3] if len(sys.argv) > 3 else "eblangpt1984.gguf" | |
| steps = int(sys.argv[4]) if len(sys.argv) > 4 else 3000 | |
| train_model(text, out, steps=steps) | |
| test_gguf(out) | |
| elif cmd == "test": | |
| test_gguf(sys.argv[2]) | |
| else: | |
| print(__doc__) | |