File size: 13,181 Bytes
d1cce78 1906a83 4bba615 d1cce78 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 1906a83 4bba615 | 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 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | ---
language:
- ru
- en
- zh
- de
- uk
tags:
- causal-lm
- pytorch
- safetensors
- timegpt
- 0.5b
- text-generation
license: apache-2.0
pipeline_tag: text-generation
inference: false
model_name: TimeGPT-Base
---
# ⏳ TimeGPT-Base (0.5B)
**TimeGPT-Base** — это мультиязычная авторегрессионная языковая модель (Causal LM) класса **0.5B**, разработанная и обученная **полностью с нуля (from scratch)** без использования сторонних весов или дистилляции.
Модель создана независимой командой **LongTime Devs** и обучена на одном потребительском ускорителе **NVIDIA GeForce RTX 5060 Ti 16GB**. Основной язык обучения — **русский**, с интеграцией английского, китайского, немецкого и украинского корпусов.
> ⚠️ **Важное замечание:** это **базовая фундаментальная модель (Base)**. Она обучена задаче продолжения текста (next-token prediction / text completion) и не проходила стадию выравнивания инструкций.
>
> Диалоговая инструктивная версия — **TimeGPT-Instruct (0.5B)** — в настоящее время находится на финальной стадии дообучения и **в скором времени будет опубликована** в репозитории команды LongTime Devs.
---
## 🏛 Архитектурные особенности
TimeGPT построена на современной архитектуре трансформера (уровня Llama 3 и Qwen 2.5), оптимизированной для высокой скорости инференса и экономии видеопамяти:
- **Grouped-Query Attention (GQA)**: 20 голов Query и 4 головы Key/Value (соотношение 5:1), что кратно снижает размер KV-кеша при работе с контекстом.
- **SwiGLU Activation**: нелинейная функция активации в блоках MLP.
- **RMSNorm**: быстрая среднеквадратичная нормализация вместо классического LayerNorm.
- **Rotary Position Embeddings (RoPE)**: векторное позиционное кодирование с базовой частотой $\theta = 500\,000$ для стабильности контекста.
- **Weight Tying**: совмещение матриц эмбеддингов токенов и выходной языковой головы для компактности и регуляризации весов.
- **FlashAttention / SDPA**: поддержка нативного аппаратного ускорения Scaled Dot-Product Attention в режиме `bfloat16`.
### Спецификация модели
| Параметр | Значение |
| :--- | :--- |
| **Класс параметров** | **0.5B** |
| **Размер файла весов** | **1.02 GB** (`model.safetensors`) |
| **Размерность скрытого слоя (`dim`)** | 1280 |
| **Количество слоев (`n_layers`)** | 24 |
| **Голов внимания (`n_heads`)** | 20 |
| **Голов Key/Value (`n_kv_heads`)** | 4 (GQA) |
| **Размерность промежуточного слоя MLP** | 3456 (SwiGLU) |
| **Контекстное окно (`max_seq_len`)** | 1024 токена |
| **Размер словаря (`vocab_size`)** | 32 000 |
| **Формат весов** | SafeTensors (`bfloat16`) |
---
## 🔤 Токенизатор
Модель использует собственный мультиязычный **Byte-Level BPE** токенизатор:
- **Размер словаря**: 32 000 токенов.
- **Byte-fallback**: байтовое резервирование исключает появление токенов неизвестных символов (`<|unk|>`) при обработке редких знаков, иероглифов и эмодзи.
- **Служебные токены стандарта ChatML**:
- `<|pad|>`
- `<|unk|>`
- `<|im_start|>`
- `<|im_end|>`
---
## 📚 Данные и процесс предобучения
Модель обучалась фундаментальному чтению в непрерывном мультиязычном потоке данных:
- **Русский язык (основной массив, ~55%)**: русскоязычный срез Википедии + новостные корпуса (`IlyaGusev/gazeta`).
- **Английский язык (~20%)**: статьи англоязычной Википедии.
- **Китайский язык (~10%)**: срез китайской Википедии.
- **Немецкий язык (~8%)**: срез немецкой Википедии.
- **Украинский язык (~7%)**: статьи украинской Википедии.
### Детали тренировочного цикла:
- **Оборудование**: 1× NVIDIA GeForce RTX 5060 Ti 16GB.
- **Шаги обучения**: 50 000 шагов (эффективный размер батча = 16 последовательностей по 1024 токена).
- **Суммарный объем прочитанных данных**: ~820 млн токенов.
- **Время непрерывного обучения**: ~27 часов.
- **Оптимизатор**: AdamW ($\beta_1 = 0.9$, $\beta_2 = 0.95$, weight decay = 0.01).
- **График Learning Rate**: Cosine Annealing с плавным разогревом (Warmup: 1500 шагов, Peak LR: `1.8e-4`).
- **Динамика Loss**: стартовый лосс **10.64** $\rightarrow$ финальный лосс **3.02–3.36** (перплексия снизилась с бесконечности до ~20).
---
## 💻 Быстрый запуск (Inference)
Установите необходимые зависимости:
```bash
pip install torch tokenizers safetensors huggingface_hub
```
Скрипт автоматически скачивает веса (`model.safetensors` — 1.02 GB) и токенизатор напрямую из репозитория `longtimedevs/TimeGPT-Base`:
```python
# WARNING: DO NOT USE THIS SCRIPT IN PRODUCTION ENVIRONMENTS! // ВНИМАНИЕ: НЕ ИСПОЛЬЗУЙТЕ ДАННЫЙ КОД В ПРОДАКШЕНЕ!
# FOR RESEARCH, TESTING AND EXPERIMENTAL PURPOSES ONLY! // ТОЛЬКО ДЛЯ ИССЛЕДОВАТЕЛЬСКИХ ЦЕЛЕЙ, ТЕСТИРОВАНИЯ И ЭКСПЕРИМЕНТОВ!
import os
import torch
import torch.nn as nn
import torch.nn.functional as F
from dataclasses import dataclass
from tokenizers import Tokenizer
from safetensors.torch import load_file
from huggingface_hub import hf_hub_download
# --- 1. Автоматическое скачивание с Hugging Face ---
REPO_ID = "longtimedevs/TimeGPT-Base"
print(f"[*] Проверка и скачивание файлов из {REPO_ID}...")
weights_path = hf_hub_download(repo_id=REPO_ID, filename="model.safetensors")
tokenizer_path = hf_hub_download(repo_id=REPO_ID, filename="tokenizer.json")
# --- 2. Конфигурация модели ---
@dataclass
class TimeGPTConfig:
vocab_size: int = 32000
dim: int = 1280
n_layers: int = 24
n_heads: int = 20
n_kv_heads: int = 4
multiple_of: int = 256
max_seq_len: int = 1024
norm_eps: float = 1e-5
rope_theta: float = 500000.0
# --- 3. Архитектура TimeGPT ---
class RMSNorm(nn.Module):
def __init__(self, dim: int, eps: float = 1e-5):
super().__init__()
self.eps = eps
self.weight = nn.Parameter(torch.ones(dim))
def forward(self, x):
return x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + self.eps) * self.weight
def precompute_rope_sincos(dim: int, max_seq_len: int, theta: float = 500000.0):
freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))
t = torch.arange(max_seq_len, dtype=torch.float32)
freqs = torch.outer(t, freqs)
freqs = torch.cat([freqs, freqs], dim=-1)
return torch.cos(freqs), torch.sin(freqs)
def rotate_half(x: torch.Tensor):
x1, x2 = x[..., : x.shape[-1] // 2], x[..., x.shape[-1] // 2 :]
return torch.cat((-x2, x1), dim=-1)
def apply_rope(xq, xk, cos, sin):
cos = cos[:xq.shape[2]].unsqueeze(0).unsqueeze(1)
sin = sin[:xq.shape[2]].unsqueeze(0).unsqueeze(1)
return (xq * cos) + (rotate_half(xq) * sin), (xk * cos) + (rotate_half(xk) * sin)
class Attention(nn.Module):
def __init__(self, cfg):
super().__init__()
self.n_heads, self.n_kv_heads = cfg.n_heads, cfg.n_kv_heads
self.head_dim = cfg.dim // cfg.n_heads
self.n_rep = self.n_heads // self.n_kv_heads
self.wq = nn.Linear(cfg.dim, cfg.n_heads * self.head_dim, bias=False)
self.wk = nn.Linear(cfg.dim, cfg.n_kv_heads * self.head_dim, bias=False)
self.wv = nn.Linear(cfg.dim, cfg.n_kv_heads * self.head_dim, bias=False)
self.wo = nn.Linear(cfg.n_heads * self.head_dim, cfg.dim, bias=False)
def forward(self, x, cos, sin):
B, S, _ = x.shape
xq = self.wq(x).view(B, S, self.n_heads, self.head_dim).transpose(1, 2)
xk = self.wk(x).view(B, S, self.n_kv_heads, self.head_dim).transpose(1, 2)
xv = self.wv(x).view(B, S, self.n_kv_heads, self.head_dim).transpose(1, 2)
xq, xk = apply_rope(xq, xk, cos, sin)
if self.n_rep > 1:
xk = xk.repeat_interleave(self.n_rep, dim=1)
xv = xv.repeat_interleave(self.n_rep, dim=1)
out = F.scaled_dot_product_attention(xq, xk, xv, is_causal=True)
return self.wo(out.transpose(1, 2).contiguous().view(B, S, -1))
class SwiGLUMLP(nn.Module):
def __init__(self, cfg):
super().__init__()
hidden_dim = int(2 * (4 * cfg.dim) / 3)
hidden_dim = cfg.multiple_of * ((hidden_dim + cfg.multiple_of - 1) // cfg.multiple_of)
self.w1 = nn.Linear(cfg.dim, hidden_dim, bias=False)
self.w2 = nn.Linear(hidden_dim, cfg.dim, bias=False)
self.w3 = nn.Linear(cfg.dim, hidden_dim, bias=False)
def forward(self, x):
return self.w2(F.silu(self.w1(x)) * self.w3(x))
class TransformerBlock(nn.Module):
def __init__(self, cfg):
super().__init__()
self.attn_norm, self.attn = RMSNorm(cfg.dim, cfg.norm_eps), Attention(cfg)
self.ffn_norm, self.ffn = RMSNorm(cfg.dim, cfg.norm_eps), SwiGLUMLP(cfg)
def forward(self, x, cos, sin):
return x + self.ffn(self.ffn_norm(x + self.attn(self.attn_norm(x), cos, sin)))
class TimeGPT(nn.Module):
def __init__(self, cfg):
super().__init__()
self.cfg = cfg
self.tok_embeddings = nn.Embedding(cfg.vocab_size, cfg.dim)
self.layers = nn.ModuleList([TransformerBlock(cfg) for _ in range(cfg.n_layers)])
self.norm = RMSNorm(cfg.dim, cfg.norm_eps)
self.output = nn.Linear(cfg.dim, cfg.vocab_size, bias=False)
self.output.weight = self.tok_embeddings.weight
cos, sin = precompute_rope_sincos(cfg.dim // cfg.n_heads, cfg.max_seq_len, cfg.rope_theta)
self.register_buffer("rope_cos", cos, persistent=False)
self.register_buffer("rope_sin", sin, persistent=False)
def forward(self, idx):
B, S = idx.shape
h = self.tok_embeddings(idx)
cos, sin = self.rope_cos[:S], self.rope_sin[:S]
for layer in self.layers:
h = layer(h, cos, sin)
return self.output(self.norm(h))
# --- 4. Загрузка весов и инференс со стримингом ---
device = "cuda" if torch.cuda.is_available() else "cpu"
cfg = TimeGPTConfig()
model = TimeGPT(cfg).to(device, dtype=torch.bfloat16)
# Чтение скачанных весов SafeTensors
weights = load_file(weights_path, device=device)
model.load_state_dict(weights, strict=False)
model.eval()
tokenizer = Tokenizer.from_file(tokenizer_path)
prompt = "Искусственный интеллект — это"
input_ids = torch.tensor([tokenizer.encode(prompt).ids], device=device)
print(prompt, end="", flush=True)
with torch.inference_mode():
for _ in range(80):
logits = model(input_ids[:, -cfg.max_seq_len:])
next_token = torch.multinomial(F.softmax(logits[0, -1, :] / 0.7, dim=-1), num_samples=1)
if next_token.item() == tokenizer.token_to_id("<|im_end|>"):
break
input_ids = torch.cat([input_ids, next_token.unsqueeze(0)], dim=1)
print(tokenizer.decode([next_token.item()]), end="", flush=True)
print()
```
---
## 👥 Разработчики
- **Команда**: LongTime Devs
- **Архитектура**: TimeGPT
- **Лицензия**: Apache 2.0 (открыто для свободного использования и исследований) |