more lil llm improvements (#17514)
Autogen / In-tree Autogen (comgr 2) (push) Successful in 47s
Unit Tests / Torch Backend Tests (push) Failing after 1m3s
Unit Tests / Linters (push) Failing after 1m27s
Unit Tests / Python Backend (push) Failing after 3m8s
Unit Tests / Fuzzing (push) Failing after 21s
Unit Tests / Docs (push) Successful in 3m32s
Unit Tests / Null Tests (push) Successful in 4m8s
Unit Tests / Unit Tests (push) Successful in 3m30s
Unit Tests / CL IMAGE Tests (push) Failing after 44s
Unit Tests / openpilot Compile Tests (push) Failing after 47s
Unit Tests / Test LLM (push) Failing after 13s
Unit Tests / SPEC=2 (1) (push) Successful in 3m53s
Deploy Docs / deploy (push) Successful in 5m1s
Unit Tests / Optimization Tests (push) Failing after 49s
Unit Tests / SPEC=2 (2) (push) Successful in 3m42s
Unit Tests / Linux (DEV=CL) (push) Failing after 38s
Unit Tests / Models (push) Successful in 1m39s
Unit Tests / Linux (DEV=CPU:X86) (push) Failing after 23s
Unit Tests / Linux (DSP) (push) Successful in 1m47s
Unit Tests / hcq2 (push) Failing after 48s
Unit Tests / Linux (am) (push) Failing after 52s
Unit Tests / Linux (DEV=CPU:LLVM) (push) Successful in 3m13s
Unit Tests / Linux (DEV=CPU:LVP) (push) Successful in 3m6s
Unit Tests / AMD ASM IDE (push) Failing after 2m46s
Unit Tests / Linux (DEV=CPU:CLANG) (push) Successful in 4m19s
Unit Tests / ONNX (CPU) Tests (push) Successful in 5m24s
Autogen / In-tree Autogen (push) Successful in 10m40s
Unit Tests / Linux (DEV=WEBGPU) (push) Failing after 5m0s
Unit Tests / Linux (amdllvm gfx1100) (push) Successful in 3m40s
Unit Tests / Linux (amd gfx1100) (push) Successful in 4m13s
Unit Tests / Linux (amdllvm gfx1201) (push) Successful in 3m35s
Unit Tests / Compile-only (DEV=NULL:IR3:a630) (push) Failing after 30s
Unit Tests / Linux (amd gfx1201) (push) Successful in 4m10s
Unit Tests / Compile-only (DEV=NULL:NAK:sm_120) (push) Failing after 28s
Unit Tests / Compile-only (DEV=NULL:QCOMCL:a630) (push) Failing after 40s
Unit Tests / Linux (amdllvm gfx950) (push) Successful in 3m36s
Unit Tests / Linux (ptx) (push) Failing after 3m17s
Unit Tests / Linux (amd gfx950) (push) Successful in 5m25s
Unit Tests / Linux (nv) (push) Failing after 5m17s
Autogen / In-tree Autogen (macos) (push) Canceled after 0s
Benchmarks / Mac pytest (push) Canceled after 0s
Benchmarks / LLM (DEV=AMD) (push) Canceled after 0s
Benchmarks / LLM (DEV=METAL) (push) Canceled after 0s
Benchmarks / LLM (DEV=NV) (push) Canceled after 0s
Benchmarks / HLB-CIFAR10 (DEV=AMD) (push) Canceled after 0s
Benchmarks / HLB-CIFAR10 (DEV=METAL) (push) Canceled after 0s
Benchmarks / HLB-CIFAR10 (DEV=NV) (push) Canceled after 0s
Benchmarks / MLPerf (AMD) (push) Canceled after 0s
Benchmarks / MLPerf (NV) (push) Canceled after 0s
Benchmarks / Stable Diffusion (DEV=AMD) (push) Canceled after 0s
Benchmarks / Stable Diffusion (DEV=METAL) (push) Canceled after 0s
Benchmarks / Stable Diffusion (DEV=NV) (push) Canceled after 0s
Benchmarks / Tests (DEV=AMD) (push) Canceled after 0s
Benchmarks / Tests (DEV=METAL) (push) Canceled after 0s
Benchmarks / Tests (DEV=NV) (push) Canceled after 0s
Benchmarks / UsbGPU Benchmark (push) Canceled after 0s
Benchmarks / comma Benchmark (0.11.2) (push) Canceled after 0s
Benchmarks / comma Benchmark (0.11.0) (push) Canceled after 0s
Benchmarks / DSP Benchmark (push) Canceled after 0s
Benchmarks / UsbGPU Benchmark (comma) (push) Canceled after 0s
Benchmarks / PCI Driver Benchmark (DEV=AMD) (push) Canceled after 0s
Benchmarks / PCI Driver Benchmark (DEV=NV) (push) Canceled after 0s
Benchmarks / LLVM Speed (push) Canceled after 0s
Platform Tests / MacOS (unit) (push) Canceled after 0s
Platform Tests / MacOS (unit, mock) (push) Canceled after 0s
Platform Tests / MacOS (DEV=METAL) (1) (push) Canceled after 0s
Platform Tests / MacOS (DEV=METAL) (2) (push) Canceled after 0s
Platform Tests / MacOS (DEV=CPU:CLANG) (push) Canceled after 0s
Platform Tests / MacOS (DEV=CPU:LLVM) (push) Canceled after 0s
Platform Tests / MacOS (DEV=CPU:LVP) (push) Canceled after 0s
Platform Tests / MacOS (DEV=WEBGPU) (push) Canceled after 0s
Platform Tests / Windows (DEV=CPU:CLANG) (push) Canceled after 0s
Platform Tests / Windows (DEV=CPU:LLVM) (push) Canceled after 0s
Platform Tests / Windows (DEV=CPU:X86) (push) Canceled after 0s
Platform Tests / Windows (DEV=WEBGPU) (push) Canceled after 0s

* more lil llm improvements

* default float
This commit is contained in:
George Hotz
2026-08-12 20:13:20 -07:00
committed by GitHub
parent 2297118541
commit e103fb2a10
2 changed files with 21 additions and 8 deletions
+10 -1
View File
@@ -13,7 +13,7 @@ V_TOKS = UOp.variable("toks", 1, 32) # 32 is the default chunk_size in generate
class TestTransformerGenerate(unittest.TestCase):
def test_warmup(self):
model, calls = Transformer(TEST_CONFIG), []
def generate(tokens):
def generate(tokens, **kwargs):
calls.append(tokens)
yield from (1, 2)
with patch.object(model, "generate", generate): model.warmup()
@@ -44,6 +44,15 @@ class TestTransformerGenerate(unittest.TestCase):
next(model.generate([1, 2, 3, 4, 5, 42, 10]))
self.assertEqual(calls, [((1, 1), V_START_POS.bind(5)), ((1, 1), V_START_POS.bind(6))])
def test_recurrent_divergent_prompt_restarts(self):
model, calls = Transformer(TEST_CONFIG), []
model.has_recurrent_block, model._cached_tokens = True, [1, 2, 9]
def mock_call(self, tokens, start_pos, temperature):
calls.append(start_pos)
return Tensor([[42]])
with patch.object(Transformer, '__call__', mock_call): next(model.generate([1, 2, 10, 11]))
self.assertEqual(calls[0], V_START_POS.bind(0))
def test_template_starts_reasoning(self):
router = StreamRouter(reasoning=True)
self.assertEqual(list(router.route("reasoning</think>answer")),
+11 -7
View File
@@ -1,7 +1,7 @@
from __future__ import annotations
import functools, itertools, pathlib
from dataclasses import dataclass, replace
from tinygrad import Tensor, nn, UOp, TinyJit, getenv, function
from tinygrad import Tensor, nn, UOp, TinyJit, getenv, function, dtypes
from tinygrad.nn import Linear
from tinygrad.llm.gguf import gguf_load
from tinygrad.uop.ops import resolve
@@ -187,8 +187,8 @@ class TransformerBlock(FFNBlock):
def _init_state(self, x:Tensor):
if not hasattr(self, "cache_kv"):
# TODO: how is the dtype of this determined?
self.cache_kv = Tensor.empty(2, x.shape[0], self.config.n_kv_heads, self.config.max_context, self.config.head_dim, device=x.device)
self.cache_kv = Tensor.empty(2, x.shape[0], self.config.n_kv_heads, self.config.max_context, self.config.head_dim,
dtype=dtypes.default_float, device=x.device)
self.freqs_cis = precompute_freqs_cis(self.config.rope_dim, self.config.max_context, self.config.rope_theta, device=x.device)
class MLATransformerBlock(FFNBlock):
@@ -261,13 +261,14 @@ class GatedDeltaNetBlock(FFNBlock):
def _attention(self, x:Tensor, start_pos:int|UOp) -> Tensor:
B, T, _ = x.shape
assert T == 1, "GatedDeltaNetBlock currently only supports T=1"
is_kda = hasattr(self, "ssm_g_a")
# input processing
x = x.half()
out_gate = self.ssm_g_b(self.ssm_g_a(x)) if hasattr(self, "ssm_g_a") else self.attn_gate(x)
out_gate = self.ssm_g_b(self.ssm_g_a(x)) if is_kda else self.attn_gate(x)
out_gate = out_gate.reshape(B, 1, self.num_v_heads, self.head_v_dim)
beta = self.ssm_beta(x).sigmoid().reshape(B, self.num_v_heads, 1, 1)
alpha = self.ssm_f_b(self.ssm_f_a(x)) if hasattr(self, "ssm_f_a") else self.ssm_alpha(x)
alpha = self.ssm_f_b(self.ssm_f_a(x)) if is_kda else self.ssm_alpha(x)
alpha = ((alpha.float() + self.ssm_dt["bias"]).softplus().reshape(B, self.num_v_heads, -1) *
self.ssm_a.reshape(1, self.num_v_heads, -1)).exp().unsqueeze(-2)
@@ -291,14 +292,13 @@ class GatedDeltaNetBlock(FFNBlock):
# output
core_attn_out = self.ssm_norm((recurrent_state@q).squeeze(-1).reshape(B, 1, self.num_v_heads, self.head_v_dim))
out_gate = out_gate.sigmoid() if hasattr(self, "ssm_g_a") else out_gate.silu()
out_gate = out_gate.sigmoid() if is_kda else out_gate.silu()
return self.ssm_out((core_attn_out * out_gate).reshape(B, 1, -1).cast(x.dtype))
# recurrent state can't be partially reused after divergence, force a full rebuild
def _state_reset_ops(self):
return [self.conv_state.assign(self.conv_state.const_like(0)),
self.recurrent_state.assign(self.recurrent_state.const_like(0))] if hasattr(self, "conv_state") else []
def _reusable_prefix_len(self, prefix_len:int, cached_len:int) -> int: return 0 if prefix_len != cached_len else prefix_len
def _init_state(self, x):
if not hasattr(self, "conv_state"):
@@ -421,6 +421,10 @@ class Transformer:
for _ in range(2): list(zip(range(2), self.generate([0])))
def get_start_pos(self, tokens:list[int]) -> int:
# recurrent state can't be partially reused after divergence: reuse it only when tokens extend the cached prefix
if self.has_recurrent_block:
return len(self._cached_tokens) if self._cached_tokens and len(self._cached_tokens) < len(tokens) \
and tokens[:len(self._cached_tokens)] == self._cached_tokens else 0
prefix_len = sum(1 for _ in itertools.takewhile(lambda ab: ab[0] == ab[1], zip(tokens[:-1], self._cached_tokens)))
return min(block._reusable_prefix_len(prefix_len, len(self._cached_tokens)) for block in self.blk)