diff --git a/docs/experiments/23-editor-tier.md b/docs/experiments/23-editor-tier.md index ce5166e6..c2f72e48 100644 --- a/docs/experiments/23-editor-tier.md +++ b/docs/experiments/23-editor-tier.md @@ -3606,3 +3606,85 @@ ZD / Z8 различимо последние в обоих свода английский исходник подаётся моделям одним блоком без авторских абзацев (наш баг экстрактора, Д-долг бэкенду) — читателям он показан таким же, каким его видели все армы, поэтому контраст честен, но материал искажён у ВСЕХ одинаково. + +## Д28 — ⭐⭐ ПЕРЕНОСИМОСТЬ ПРОМТА-РОЛИ: ВЕРДИКТ. И конфаунд, который решал всё + +13 глав английской пары, 6 армов, один читатель на главу, сессия #97. Сборка сверена: 78 текстов +побайтно против клеток, 13 разных раскладок, совпадающих армов нет. Аудит: 13 читателей, по 3–4 +вызова, по 2 пути, нарушений 0, чужих глав 0. + +### Д28.1 Порядок и контрасты + +``` +арм ср. место что это +RGT 2.54 тот же промт на glm-5 С РАЗМЫШЛЕНИЕМ +RN 2.62 тот же промт на deepseek-v4-pro ← ЯКОРЬ пре-рега Д25 +ZF 2.85 боевая связка, 2-я генерация +Z0 3.08 боевая связка, продакшен +RK 4.77 тот же промт на grok-4.3 +RG 5.15 тот же промт на glm-5 БЕЗ размышления + +пол Z0/ZF: +0.23 при пороге 1.43 — НЕразличимы, как обязаны (контроль ЗЕЛЁНЫЙ) +⚠ грубого декоя в этой панели НЕТ: разрешение прибора держится только на близнецах + +якорь ↔ RGT −0.08 порог 1.86 в пределах знаковый p=0.5811 +якорь ↔ ZF +0.23 порог 1.40 в пределах p=0.5811 +якорь ↔ Z0 +0.46 порог 1.69 в пределах p=0.2668 +якорь ↔ RK +2.15 порог 1.95 РАЗЛИЧИМ p=0.0923 (порогом да, знаковым на грани) +якорь ↔ RG +2.54 порог 1.20 РАЗЛИЧИМ p=0.0034 (обоими приборами) +``` + +### Д28.2 ВЕРДИКТ по правилу, объявленному ДО данных + +1. **Промт-роль ПЕРЕНОСИМ на `glm-5` — при условии, что модель думает.** Разрыв −0.08 при пороге + 1.86; более того, `RGT` забрал верхнее среднее место панели. Это первый арм за всю дугу, вставший + выше боевой связки, — но разрыв со связкой тоже в пределах порога, так что «выше» здесь означает + «не хуже». +2. **НЕ переносим на `grok-4.3`** (+2.15 при пороге 1.95). Оговорка честная: порогом различим, + знаковым тестом p=0.0923 — на грани. Вывод стоит на одном из двух приборов. +3. **НЕ переносим на `glm-5` без размышления** (+2.54 при пороге 1.20, оба прибора согласны). + +### Д28.3 ⭐⭐ ГЛАВНОЕ: конфаунд, пойманный ДО судейства, перевернул бы вывод + +Если бы эррата Д25.1 не была найдена, в панели стоял бы ОДИН `glm-5` — тот, которому ростер гасит +размышление. Вывод звучал бы: **«промт-роль не переносится на glm-5»**. Он был бы ЛОЖНЫМ ровно +наоборот: с размышлением этот же вендор идёт вровень с `deepseek-v4-pro` и возглавляет панель. + +⇒ Норма, которую это заводит: **конфигурация модели — часть арма, а не фон.** Вендор-дефолт, +переопределённый нашим ростером, обязан быть НАЗВАН в пре-реге панели наравне с моделью. + +### Д28.4 ⭐ КРОСС-ВЕНДОРНОЕ ПОДТВЕРЖДЕНИЕ МЕХАНИЗМА ТРЕЙСА + +Трейс 20.08 (53 клетки, `deepseek-v4-pro`) показал: 88–94% финального текста модель пишет ВНУТРИ +размышления, то есть размышление у неё — ЧЕРНОВИК, а не проверка. Из этого следовало предсказание: +выключи размышление — и качество упадёт различимо. + +**Предсказание проверено на ДРУГОМ вендоре и подтвердилось:** один и тот же `glm-5`, один и тот же +промт, одни и те же 13 глав — с размышлением 2.54 (вровень с dspro), без размышления 5.15 +(различимо хуже, оба прибора). Разрыв внутри одной модели **+2.61 места**. + +Это первое подтверждение механизма, не опирающееся на трейс DeepSeek, — и самое сильное, потому +что получено вслепую: читатели не знали ни моделей, ни конфигураций. + +### Д28.5 ⛔ ЧТО ЭТО ЗНАЧИТ ДЛЯ ДЕНЕГ — и почему дешёвого вендора не нашлось + +``` +арм модель, конфигурация $/клетка размышление вердикт +RG glm-5, думание ВЫКЛ 0.0029 0 различимо ХУЖЕ +RK grok-4.3 0.0068 737 различимо ХУЖЕ +RN deepseek-v4-pro 0.0278 6 139 якорь +RGT glm-5, думание ВКЛ 0.0572 16 879 НЕ ХУЖЕ, но ВДВОЕ дороже +``` + +⇒ **Оба дешёвых варианта различимо хуже, а равный по качеству — вдвое дороже якоря.** +Замена жильца в роли однопроходки денег НЕ экономит: **платим мы не за вендора, а за размышление**, +и цена качества у обоих семейств оказалась одного порядка. +⇒ Практический вывод для продукта: **`deepseek-v4-pro` в этой роли остаётся оптимумом цена/качество, +а `glm-5` с размышлением — валидный ЗАПАСНОЙ жилец** (вендор-независимость, важная при квотах и +цензуре), за который придётся доплатить вдвое. + +### Д28.6 Чего замер не может + +Одно судейское семейство · один читатель на главу · грубого декоя в панели нет · английская пара · +n=13 (две главы недособраны: гард кассы отказал на потолке ФД-N, недостающая сумма $0.11 названа +владельцу, потолок сессией НЕ поднимался). diff --git a/eval/dovodka/rol.py b/eval/dovodka/rol.py index 34991d0e..7d893a33 100644 --- a/eval/dovodka/rol.py +++ b/eval/dovodka/rol.py @@ -921,7 +921,7 @@ def verify_read(tag_: str, p: str) -> int: return 1 if bad else 0 -def score_arch(tag_: str = "arch2", p: str = "en", drop: tuple = ()) -> int: +def score_arch(tag_: str = "arch2", p: str = "en", drop: tuple = (), anchor: str = "") -> int: """`drop` — РЫЧАГ ЧУВСТВИТЕЛЬНОСТИ, не способ получить нужный ответ. Печатается в шапке свода, и вывод, который живёт только при выброшенной главе, обязан называться вместе с ней.""" keys = sorted((OUT / "blind-keys-rol").glob(f"rol-KEY-{tag_}-*.json")) @@ -949,12 +949,13 @@ def score_arch(tag_: str = "arch2", p: str = "en", drop: tuple = ()) -> int: for arm, v in r.items(): ranks.setdefault(arm, []).append(v) twins.append(abs(r["Z0"] - r["ZF"])) - decoy.append(r["ZD"]) + if "ZD" in r: # грубый декой стоит не в каждой панели + decoy.append(r["ZD"]) # ⚠ КОНТРОЛЬ ТОЖДЕСТВА, найденный чтением: на главах без канон-щелей `Z7` — побайтная копия # `ZP` (фиксер не звался). Читатель, разводящий два ОДИНАКОВЫХ текста, не имеет разрешения. var = _variants(READ_DIR / f"ЧТЕНИЕ-{p}-{tag_}-{uid8}.md") rev = {v: k for k, v in lay.items()} - if var.get(rev["Z7"]) == var.get(rev["ZP"]): + if "Z7" in r and "ZP" in r and var.get(rev["Z7"]) == var.get(rev["ZP"]): ident.append((uid8, abs(r["Z7"] - r["ZP"]))) n = len(twins) print(f"\n=== СВОД {tag_}, пара {p}: глав отсужено {n} из {len(keys)} ===" @@ -969,8 +970,12 @@ def score_arch(tag_: str = "arch2", p: str = "en", drop: tuple = ()) -> int: f"{' '.join(f'{x:g}' for x in v)}") print(f"\nКОНТРОЛЬ ШУМА |Z0−ZF| среднее {sum(twins) / n:.2f} из {len(ranks)} мест " f"· помест-но {' '.join(f'{x:g}' for x in twins)}") - print(f"КОНТРОЛЬ ДЕКОЯ ZD среднее место {sum(decoy) / n:.2f} " - f"(обязан быть внизу; {sum(1 for x in decoy if x > len(ranks) / 2)} из {n} в нижней половине)") + if decoy: + print(f"КОНТРОЛЬ ДЕКОЯ ZD среднее место {sum(decoy) / n:.2f} (обязан быть внизу; " + f"{sum(1 for x in decoy if x > len(ranks) / 2)} из {n} в нижней половине)") + else: + print("КОНТРОЛЬ ДЕКОЯ: грубого декоя в этой панели НЕТ — " + "разрешение прибора держится только на близнецах") # ⚠ КОНТРАСТЫ ПАРНЫЕ И МЕРИЛО У НИХ — БЛИЗНЕЦЫ, А НЕ НОЛЬ. Два прогона ОДНОГО способа расходятся # по главам; значит «арм A выше арма B» что-то значит, только если разрыв больше того, что тот # же прибор показывает между `Z0` и `ZF`. Точный знаковый тест берётся у `zsud`, своего не пишем. @@ -979,13 +984,19 @@ def score_arch(tag_: str = "arch2", p: str = "en", drop: tuple = ()) -> int: print(f"\nПАРНЫЕ КОНТРАСТЫ (n={n}). Собственный пол: близнецы Z0/ZF расходятся на " f"{st.mean(tw):+.2f} места при пороге {2.8 * st.pstdev(tw) / n ** 0.5:.2f} — " f"{'НЕразличимы, как и обязаны' if abs(st.mean(tw)) <= 2.8 * st.pstdev(tw) / n ** 0.5 else '⛔ РАЗЛИЧИМЫ, пол негоден'}") - base = [(a + b) / 2 for a, b in zip(ranks["Z0"], ranks["ZF"])] + # ⚠ ЯКОРЬ КОНТРАСТА — ПАРАМЕТР. Для панели архитектур это боевая связка; для панели + # переносимости пре-рег Д25 назначил якорем `RN` — тот же промт на `deepseek-v4-pro`, + # иначе замер сравнивал бы вендоров с ДРУГОЙ архитектурой, а не промт с самим собой. + skip = (anchor,) if anchor in ranks else ("Z0", "ZF") + base = ranks[anchor] if anchor in ranks else [ + (a + b) / 2 for a, b in zip(ranks["Z0"], ranks["ZF"])] + print(f"якорь контраста: {anchor if anchor in ranks else 'связка Z0/ZF'}") for arm in sorted(ranks, key=lambda x: sum(ranks[x]) / n): - if arm in ("Z0", "ZF"): + if arm in skip: continue - d = [x - y for x, y in zip(ranks[arm], base)] # >0 — арм ХУЖЕ связки + d = [x - y for x, y in zip(ranks[arm], base)] # >0 — арм ХУЖЕ якоря mde = 2.8 * st.pstdev(d) / n ** 0.5 # форма порога из пре-рега Д23.3 - print(f" связка ↔ {arm:4s} разрыв {st.mean(d):+5.2f} места · порог {mde:4.2f} · " + print(f" якорь ↔ {arm:4s} разрыв {st.mean(d):+5.2f} места · порог {mde:4.2f} · " f"{'РАЗЛИЧИМ ' if abs(st.mean(d)) > mde else 'в пределах'} · " f"знаковый p={ZS._sign_p(d):.4f}") # noqa: SLF001 if ident: @@ -1041,7 +1052,8 @@ if __name__ == "__main__": elif a[0] == "--score-arch": _tag = next((x.split("=", 1)[1] for x in a if x.startswith("--tag=")), "arch2") _drop = tuple(next((x.split("=", 1)[1].split(",") for x in a if x.startswith("--drop=")), [])) - sys.exit(score_arch(_tag, next((x for x in a[1:] if x in PAIRS), "en"), _drop)) + _anch = next((x.split("=", 1)[1] for x in a if x.startswith("--anchor=")), "") + sys.exit(score_arch(_tag, next((x for x in a[1:] if x in PAIRS), "en"), _drop, _anch)) elif a[0] == "--coverage": for p in ([x for x in a[1:] if x in PAIRS] or list(PAIRS)): print(f"\n=== ПОКРЫТИЕ БОЕВЫХ ПРОМТОВ, пара {p} ===")