t27.aiEnglish

Прогон, который ничего не проверил

Вы узнаете

Что такое пустой проход, почему зелёный отчёт может его скрыть и как подложенная ошибка отличает настоящие проверки от пустых.

Нативный t27c запускает все 13 тестов gfternary.t27, и все 13 проходят. Тот же отчёт печатает строку, которой нет у большинства инструментов: 8 из 13 прошли, не выполнив ни одного assert во время работы. Пустой проход — не ложь, но и не доказательство. 5 инвариантов доказываются, пока спека компилируется, и один из них утверждает только true — это заглушка. Поэтому запись подкладывает ошибку: зарезервированный код 11 больше не сворачивается в ноль. Падает ровно один тест — тот, что написан для этого правила. Каждый байт в записи напечатала команда; инсценирован только набор текста.

Попробуйте

Найдите строку о пустых проходах и тест, который ломает подложенная ошибка; затем откройте спеку и найдите инвариант, который утверждает только true.

Открыть интерактивный урок →

t27c on gfternary.t27 -- phi-scaled ternary weights, native
t27c on gfternary.t27 -- phi-scaled ternary weights, native ↗

t27c 0.4.0 and zig 0.16.0 on the t27c lab (Railway), spec at t27 5ff0ec512: 13 tests pass natively, 8 of them with no runtime assert; dropping the reserved-code fold makes exactly one test fail; git restores the spec.

specs/numeric/gfternary.t27

// SPDX-License-Identifier: Apache-2.0
; gfternary.t27 0 GFTernary Format Specification
; 2-bit golden-ratio ternary: representable values { -phi, 0, +phi }
; The phi-scaled limit of the ternary-weight family: GFTernary = phi * {-1,0,+1}
; (a ternary-weight quantizer, cf. TWN / BitNet, with the scale fixed at phi).
; phi^2 + phi^-2 = 3 | TRINITY

module triformat-gaternary;

// ============================================================================
// Constants
// ============================================================================

// Golden ratio phi = (1 + sqrt(5)) / 2 and its reciprocal phi^-1 = phi - 1.
pub const PHI : f64 = 1.6180339887498949;
pub const PHI_INV : f64 = 0.6180339887498949;

// 2-bit code points, stored in the low two bits of a u8 container.
pub const CODE_MASK : u8 = 0x03;
pub const GAT_ZERO : u8 = 0x00;   // 0b00 -> 0
pub const GAT_POS  : u8 = 0x01;   // 0b01 -> +phi
pub const GAT_NEG  : u8 = 0x02;   // 0b10 -> -phi
pub const GAT_RSVD : u8 = 0x03;   // 0b11 -> reserved (folds to zero)

// ============================================================================
// Types
// ============================================================================

pub const GFTernary = u8;

// ============================================================================
// Core functions
// ============================================================================

// gat_canonical(code) GFTernary
// Mask to the low two bits and fold the reserved code 0b11 onto zero.
pub fn gat_canonical(code: GFTernary) GFTernary {
    const c = code & CODE_MASK;
    return if (c == GAT_RSVD) GAT_ZERO else c;
}

// gat_is_zero(code) bool
pub fn gat_is_zero(code: GFTernary) bool {
    return gat_canonical(code) == GAT_ZERO;
}

// gat_sign(code) i8 -> -1, 0, +1
pub fn gat_sign(code: GFTernary) i8 {
    const c = gat_canonical(code);
    return if (c == GAT_POS) 1 else if (c == GAT_NEG) -1 else 0;
}

// gat_from_sign(s) GFTernary  (s in {-1, 0, +1})
pub fn gat_from_sign(s: i8) GFTernary {
    return if (s > 0) GAT_POS else if (s < 0) GAT_NEG else GAT_ZERO;
}

// gat_negate(code) GFTernary  -- flips +phi <-> -phi, zero is fixed.
pub fn gat_negate(code: GFTernary) GFTernary {
    const c = gat_canonical(code);
    return if (c == GAT_POS) GAT_NEG else if (c == GAT_NEG) GAT_POS else GAT_ZERO;
}

// gat_to_f64(code) f64 -> { +PHI, -PHI, 0.0 }
pub fn gat_to_f64(code: GFTernary) f64 {
    const c = gat_canonical(code);
    return if (c == GAT_POS) PHI else if (c == GAT_NEG) -PHI else 0.0;
}

// gat_from_f64(value, threshold) GFTernary
// Ternary-weight quantizer with fixed phi scale (TWN with alpha = phi):
//   |value| <= |threshold|        -> 0
//   value   >  |threshold|        -> +phi
//   value   < -|threshold|        -> -phi
pub fn gat_from_f64(value: f64, threshold: f64) GFTernary {
    const t = if (threshold < 0.0) -threshold else threshold;
    if (value > t) return GAT_POS;
    if (value < -t) return GAT_NEG;
    return GAT_ZERO;
}

// ============================================================================
// Tests (L4 TESTABILITY). f64 checks use a tolerance (L5 IDENTITY).
// ============================================================================

test "gat_three_representable_values" {
    const dp = gat_to_f64(GAT_POS) - PHI;
    const dn = gat_to_f64(GAT_NEG) + PHI;
    try std.testing.expect(gat_to_f64(GAT_ZERO) == 0.0);
    try std.testing.expect(dp > -1e-12 and dp < 1e-12);
    try std.testing.expect(dn > -1e-12 and dn < 1e-12);
}

test "gat_reserved_code_folds_to_zero" {
    try std.testing.expect(gat_is_zero(GAT_RSVD));
    try std.testing.expect(gat_to_f64(GAT_RSVD) == 0.0);
}

test "gat_negate_symmetry" {
    const d = gat_to_f64(gat_negate(GAT_POS)) + PHI;
    try std.testing.expect(d > -1e-12 and d < 1e-12);
    try std.testing.expect(gat_negate(GAT_ZERO) == GAT_ZERO);
}

test "gat_sign_roundtrip" {
    try std.testing.expect(gat_from_sign(gat_sign(GAT_POS)) == GAT_POS);
    try std.testing.expect(gat_from_sign(gat_sign(GAT_NEG)) == GAT_NEG);
    try std.testing.expect(gat_from_sign(gat_sign(GAT_ZERO)) == GAT_ZERO);
}

test "gat_quantizer_threshold" {
    try std.testing.expect(gat_from_f64(2.0, 0.5) == GAT_POS);
    try std.testing.expect(gat_from_f64(-2.0, 0.5) == GAT_NEG);
    try std.testing.expect(gat_from_f64(0.1, 0.5) == GAT_ZERO);
}

// L5 IDENTITY: phi^2 = phi + 1; phi^2 + phi^-2 = 3; phi * phi^-1 = 1.
test "gat_phi_identity_l5" {
    const d1 = PHI * PHI - (PHI + 1.0);
    const d2 = PHI * PHI + PHI_INV * PHI_INV - 3.0;
    const d3 = PHI * PHI_INV - 1.0;
    try std.testing.expect(d1 > -1e-12 and d1 < 1e-12);
    try std.testing.expect(d2 > -1e-12 and d2 < 1e-12);
    try std.testing.expect(d3 > -1e-12 and d3 < 1e-12);
}

// ============================================================================
// Bench (L4 TESTABILITY)
// ============================================================================

bench "bench_gft_decode_latency" {
    // measure: nanoseconds to decode a code to f64
    // target: < 20ns (mask + two compares)
    @setEvalBranchQuota(10000);
    var result: f64 = 0.0;
    const code: GFTernary = GAT_NEG;
    for (0..1000) |_| {
        result = gat_to_f64(code);
    }
    _ = result;
}

bench "bench_gft_quantize_latency" {
    // measure: nanoseconds to ternary-quantize one f64 with a threshold
    // target: < 30ns (abs + two compares)
    @setEvalBranchQuota(10000);
    var result: GFTernary = 0;
    const v: f64 = 1.3;
    const thr: f64 = 0.5;
    for (0..1000) |_| {
        result = gat_from_f64(v, thr);
    }
    _ = result;
}

// =====================================================================
// Phase C1/C2 (epic #181) -- GFTernary {-phi,0,+phi} vs BitNet {-1,0,+1} (appended)
// Falsification: phi-ternary within MC error of integer-ternary => phi-scale falsified.
// =====================================================================

pub const INT_TERNARY_SCALE : f64 = 1.0;

// GFTernary arm scale (phi -- defined in existing constants above as PHI).
// [Open conjecture]: phi scale may improve over int-ternary; not proven.
// pub const PHI already defined above; re-reference only.

// Scaled ternary arm: alpha = PHI used as initial guess; to be optimised.
// This arm checks whether ANY fixed scale beats tuned alpha.
pub const SCALED_TERNARY_INIT_ALPHA : f64 = PHI;

// MC error threshold: below this delta in BPB the claim is falsified.
pub const MC_ERROR_BPB : f64 = 0.003;

// GFTernary weight L2-norm per element (for normalisation comparison).
// gat_weight_l2 = phi (non-zero arms); int_ternary_weight_l2 = 1.0.
// A scale factor of phi inflates norms -- must be tracked in comparison.
pub const GAT_WEIGHT_NORM : f64 = PHI;
pub const INT_TERNARY_WEIGHT_NORM : f64 = INT_TERNARY_SCALE;

// ============================================================================
// C1 Tests (L4 TESTABILITY)
// ============================================================================

test "gat_control_arm_definitions" {
    // Arm A: GFTernary scale is phi
    const arm_a_scale : f64 = PHI;
    // Arm B: IntTernary scale is exactly 1.0
    const arm_b_scale : f64 = INT_TERNARY_SCALE;
    // Arm C: ScaledTernary initial alpha = phi (will be optimised)
    const arm_c_init : f64 = SCALED_TERNARY_INIT_ALPHA;
    // Assert phi scale is not trivially the same as int-ternary scale.
    const d_ab = arm_a_scale - arm_b_scale;
    try std.testing.expect(d_ab > 0.5);  // phi - 1 ~ 0.618 > 0.5
    // Assert arm C initialises at phi (same as arm A)
    const d_ac = arm_a_scale - arm_c_init;
    try std.testing.expect(d_ac > -1e-12 and d_ac < 1e-12);
}

test "gat_falsification_criterion_bpb_gap" {
    // Given: bpb_gft (arm A) and bpb_int (arm B) from a hypothetical run.
    // The test checks the logic: claim survives iff gap > MC_ERROR_BPB.
    //
    // Scenario 1: GFTernary wins by more than MC error => claim survives.
    const bpb_gft_wins : f64 = 2.195;
    const bpb_int_ref  : f64 = 2.210;
    const gap_wins = bpb_int_ref - bpb_gft_wins;
    try std.testing.expect(gap_wins > MC_ERROR_BPB);  // 0.015 > 0.003

    // Scenario 2: Gap is within MC error => phi-specificity falsified.
    const bpb_gft_tied : f64 = 2.209;
    const gap_tied = bpb_int_ref - bpb_gft_tied;
    // gap_tied = 0.001 < 0.003 => falsified; confirm the arithmetic:
    try std.testing.expect(gap_tied < MC_ERROR_BPB);

    // Scenario 3: IntTernary wins => phi-specificity also falsified.
    const bpb_gft_worse : f64 = 2.215;
    const gap_worse = bpb_int_ref - bpb_gft_worse;
    // gap_worse < 0 => falsified
    try std.testing.expect(gap_worse < 0.0);
}

test "gat_weight_norm_ratio" {
    // GFT weights have L2 norm phi per non-zero element.
    // Int-ternary weights have L2 norm 1.0.
    // Ratio = phi; must be accounted for in effective learning-rate comparison.
    const ratio = GAT_WEIGHT_NORM / INT_TERNARY_WEIGHT_NORM;
    const expected_ratio = PHI;
    const d = ratio - expected_ratio;
    try std.testing.expect(d > -1e-12 and d < 1e-12);
}

test "gat_mc_error_threshold_positive" {
    // MC_ERROR_BPB must be strictly positive and small.
    try std.testing.expect(MC_ERROR_BPB > 0.0);
    try std.testing.expect(MC_ERROR_BPB < 0.01);
}

test "gat_phi_l5_identity_in_ablation_context" {
    // L5 IDENTITY: phi^2 + phi^-2 = 3 holds exactly for the scale constant.
    // [Verified] -- the ONLY verified phi fact.
    const phi2 = PHI * PHI;
    const phiinv2 = PHI_INV * PHI_INV;
    const trinity = phi2 + phiinv2;
    const d = trinity - 3.0;
    try std.testing.expect(d > -1e-12 and d < 1e-12);
}

// ============================================================================
// C1 Invariants (L4 TESTABILITY)
// ============================================================================

invariant "gat_phi_scale_distinct_from_unit" {
    // phi != 1.0 -- the ternary arms are numerically different.
    // [Verified trivially from phi definition; not a conjecture.]
    @compileAssert(PHI > 1.5);          // phi ~ 1.618
    @compileAssert(INT_TERNARY_SCALE == 1.0);
}

invariant "gat_integer_ternary_scale_unit" {
    // The integer ternary baseline (BitNet b1.58) uses scale exactly 1.0.
    @compileAssert(INT_TERNARY_SCALE == 1.0);
}

invariant "gat_mc_error_positive" {
    // MC error threshold must be positive to be a valid falsification bound.
    @compileAssert(MC_ERROR_BPB > 0.0);
}

invariant "gat_arm_scales_distinct" {
    // Arms A and B must have different scales to be a real ablation.
    // PHI > 1.0 == INT_TERNARY_SCALE is guaranteed by phi > 1.
    @compileAssert(PHI > INT_TERNARY_SCALE);
}

invariant "gat_claim_status_open_conjecture" {
    // [Open conjecture]: phi ternary scale superiority over int-ternary is NOT
    // proven by any theorem in this repo. The claim requires the control test.
    // This invariant enforces that no assertion in this file claims it proven.
    @compileAssert(true);  // structural placeholder -- human reviewer checks above
}

// ============================================================================
// C2 -- CPU Inference Baseline (bitnet.cpp / IGLA Cramming Regime)
//
// Reference: Wang et al. 2024, "1-bit LLM: The Era of 1-bit Large Language
//   Models for All", arXiv 2410.16144 (bitnet.cpp CPU kernel).
// Context: Geiping & Goldstein 2022, "Cramming: Training a Language Model on
//   a Single GPU in One Day" -- IGLA regime uses single-GPU training with
//   CPU inference cost as deployment metric.
// Architecture target: SmolLM2 hidden=384, 1-layer ternary linear for bench.
//
// FALSIFICATION context: if GFTernary MAC throughput on CPU is more than 2x
//   slower than IntTernary at equal sparsity (~1/3 non-zero), then GFTernary
//   is disqualified on practical grounds even if BPB is competitive.
// ============================================================================

// Sparsity constant: approximately 1/3 of ternary weights are non-zero
//   (expected for a balanced ternary distribution at threshold 0.5).
pub const TERNARY_NONZERO_FRACTION : f64 = 0.333;

// Width of the linear layer in the CPU bench (SmolLM2 hidden=384).
pub const BENCH_HIDDEN_DIM : u32 = 384;

// Maximum allowed latency ratio: GFT over IntTernary. Above this the
// GFTernary format is impractical for CPU inference.
pub const MAX_LATENCY_RATIO : f64 = 2.0;

// ============================================================================
// C2 Tests
// ============================================================================

test "gat_cpu_bench_constants_sane" {
    // Hidden dim = 384 matches the SmolLM2/IGLA champion config.
    try std.testing.expect(BENCH_HIDDEN_DIM == 384);
    // Non-zero fraction is approximately 1/3.
    const d = TERNARY_NONZERO_FRACTION - 0.333;
    try std.testing.expect(d > -1e-3 and d < 1e-3);
    // Max ratio bound is 2.0 (practical deployment gate).
    try std.testing.expect(MAX_LATENCY_RATIO == 2.0);
}

test "gat_cpu_latency_ratio_gate" {
    // Simulated scenario: ratio 1.05 (GFT 5% slower than IntTernary).
    // A ratio below MAX_LATENCY_RATIO is acceptable.
    const simulated_ratio : f64 = 1.05;
    try std.testing.expect(simulated_ratio < MAX_LATENCY_RATIO);

    // Simulated scenario: ratio 2.5 => GFTernary fails the practical gate.
    const failing_ratio : f64 = 2.5;
    try std.testing.expect(failing_ratio > MAX_LATENCY_RATIO);
}

// ============================================================================
// C2 Bench (L4 TESTABILITY)
// ============================================================================

bench "bench_gft_vs_int_ternary_mac" {
    // Measures: MAC throughput for a ternary-weight matrix-vector product
    //   of shape (BENCH_HIDDEN_DIM x BENCH_HIDDEN_DIM) at ~1/3 sparsity.
    // Compares two code paths:
    //   (a) GFTernary: decode GAT_NEG/GAT_POS to +/-phi, multiply.
    //   (b) IntTernary: decode to +/-1, multiply (same branch structure).
    // Difference: GFTernary multiplies by phi (a float multiply) vs 1.0
    //   (which compilers may elide). This bench quantifies that overhead.
    // Target: ratio (a)/(b) < MAX_LATENCY_RATIO = 2.0.
    //
    // Relation to bitnet.cpp (arXiv 2410.16144): that paper reports
    //   ~1.37 tok/s per W speedup on CPU vs FP16 for int-ternary.
    //   GFTernary must not erode that speedup by more than 2x to remain
    //   competitive in the IGLA CPU inference regime.
    @setEvalBranchQuota(100000);
    const N : usize = BENCH_HIDDEN_DIM;
    var sum_gft : f64 = 0.0;
    var sum_int : f64 = 0.0;
    const codes : [4]GFTernary = [GAT_ZERO, GAT_POS, GAT_NEG, GAT_ZERO];
    const signs : [4]i8 = [0, 1, -1, 0];
    for (0..N) |i| {
        const idx = i & 3;
        // GFTernary path: multiply by phi
        sum_gft += gat_to_f64(codes[idx]) * 0.5;
        // IntTernary path: multiply by sign (no phi scale)
        sum_int += @as(f64, @floatFromInt(signs[idx])) * 0.5;
    }
    _ = sum_gft;
    _ = sum_int;
}

bench "bench_gft_cpu_inference_bitnet_baseline" {
    // End-to-end latency proxy: decode one row of BENCH_HIDDEN_DIM ternary
    //   weights and accumulate dot product with a f64 input vector.
    // This is the inner loop of a ternary linear layer on CPU.
    // Reference: bitnet.cpp reports sub-2ns/op on modern x86 for int-ternary;
    //   GFTernary target: < 4ns/op (2x tolerance per MAX_LATENCY_RATIO).
    @setEvalBranchQuota(100000);
    const N : usize = BENCH_HIDDEN_DIM;
    var acc : f64 = 0.0;
    var code : GFTernary = GAT_POS;
    for (0..N) |_| {
        // GFTernary decode + multiply (the critical inner loop operation)
        acc += gat_to_f64(code) * 0.25;
        code = gat_canonical(code + 1);
    }
    _ = acc;
}

Открыть спеку урока в плеере ↗

Все уроки