Spaces:
Running
feat: add global debug switch and unified debug logging system
Browse files- Global configuration module
- DEBUG = False (default: silent)
- Single line to toggle all debug output across entire codebase
- Unified debug output utilities
- dlog(lines, msg): appends [DEBUG] msg to UI log list (for metrics/analyze)
- dprint(msg): prints to stdout (for fetcher, no access to lines)
- Both functions are no-ops when DEBUG=False, zero performance impact
- Replaced all print() with dprint()
- Debug info covered:
- tensor_name, shape, dtype
- data_offsets (raw and absolute)
- expected_bytes vs actual_bytes check โ
/โ
- first 8 bytes hex (for cross-validation with local file reader)
- result[0,:5] (first row sanity check)
- All controlled by DEBUG switch, zero output in production
- Replaced all log.append("[DEBUG]...") with dlog(lines, ...)
- Debug info covered:
- key_q / key_k / key_v (full key names)
- W_q / W_k / W_v shapes
- n_q / n_kv / group / d_head / head_dim_source
- W_k[0,:10] / W_q[0,:10] raw weights (for cross-validation)
- Per KV head: k_t shape, s_kๅ5, k_t[0,:10]
- Per Q head: q_t shape, s_qๅ5, q_t[0,:10]
- Per Q head: pearson, alpha_QK, s_q[0], s_k[0]
- Added dlog() for shard/key/offset info before tensor loading
- Debug info covered:
- q/k/v shard filename
- q/k/v full key name
- k_header_size
- k_offsets (raw data_offsets)
- k_abs_start (= 8 + header_size + offset, the actual HTTP Range start)
During cross-validation of gemma-4-31b-it against reference implementation:
Reference code result: K head0 sigma_max = 393.07 (wrong)
Our result: K head0 sigma_max = 4.40 (correct)
Root cause found via debug output:
Reference code bug in load_tensor_from_file():
f.seek(start) # โ offset relative to data section
f.seek(8 + header_len + start) # โ
correct absolute file offset
gemma-4-31b-it header_size โ 136KB
โ seek error = 136KB = ~13 rows of BF16 data
โ KV head0 first row completely wrong
โ sigma_max inflated from 4.40 to 393.07
Smaller models (gemma-4-e2b, Qwen2.5, LLaMA-3) not affected because
their early tensor offsets start near 0, masking the seek error.
Our HTTP Range Request implementation was correct throughout:
abs_start = 8 + header_size + offsets[0] โ
# Enable debug (cross-validation, new model investigation):
# core/config.py
DEBUG = True
# Disable debug (production):
DEBUG = False
One line change, all debug output across fetcher/metrics/analyze
synchronized instantly.
- core/config.py +21 -0
- core/debug.py +26 -0
- core/fetcher.py +5 -3
- core/metrics.py +28 -23
- ui/tab_analyze.py +11 -0
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# core/config.py
|
| 2 |
+
"""
|
| 3 |
+
ๅ
จๅฑ้
็ฝฎๅผๅ
ณ
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 7 |
+
# Debug ๅผๅ
ณ
|
| 8 |
+
# True โ ๆๅฐ่ฏฆ็ป่ฐ่ฏไฟกๆฏๅฐๆฅๅฟ
|
| 9 |
+
# False โ ้้ป่ฟ่ก๏ผๅช่พๅบ็ปๆ
|
| 10 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 11 |
+
DEBUG = False# core/config.py
|
| 12 |
+
"""
|
| 13 |
+
ๅ
จๅฑ้
็ฝฎๅผๅ
ณ
|
| 14 |
+
"""
|
| 15 |
+
|
| 16 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 17 |
+
# Debug ๅผๅ
ณ
|
| 18 |
+
# True โ ๆๅฐ่ฏฆ็ป่ฐ่ฏไฟกๆฏๅฐๆฅๅฟ
|
| 19 |
+
# False โ ้้ป่ฟ่ก๏ผๅช่พๅบ็ปๆ
|
| 20 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 21 |
+
DEBUG = False
|
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# core/debug.py
|
| 2 |
+
"""
|
| 3 |
+
่ฐ่ฏ่พๅบๅทฅๅ
ท
|
| 4 |
+
ๆๆ่ฐ่ฏไฟกๆฏ็ปไธ่ตฐ่ฟ้๏ผๅ DEBUG ๅผๅ
ณๆงๅถ
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from core.config import DEBUG
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def dlog(lines: list[str], msg: str):
|
| 11 |
+
"""
|
| 12 |
+
ๅ lines ่ฟฝๅ ่ฐ่ฏไฟกๆฏ๏ผไป
DEBUG=True ๆถ๏ผ
|
| 13 |
+
lines: ๆฅๅฟ่กๅ่กจ๏ผไผ ๅผ็จ๏ผ็ดๆฅ append๏ผ
|
| 14 |
+
msg: ่ฐ่ฏไฟกๆฏๅญ็ฌฆไธฒ
|
| 15 |
+
"""
|
| 16 |
+
if DEBUG:
|
| 17 |
+
lines.append(f"[DEBUG] {msg}\n")
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def dprint(msg: str):
|
| 21 |
+
"""
|
| 22 |
+
ๆๅฐๅฐ stdout๏ผไป
DEBUG=True ๆถ๏ผ
|
| 23 |
+
็จไบ fetcher.py ็ญๆ ๆณ่ฎฟ้ฎ lines ็ๅฐๆน
|
| 24 |
+
"""
|
| 25 |
+
if DEBUG:
|
| 26 |
+
print(f"[DEBUG] {msg}")
|
|
@@ -9,6 +9,8 @@ import json
|
|
| 9 |
import requests
|
| 10 |
import torch
|
| 11 |
from huggingface_hub import list_repo_files
|
|
|
|
|
|
|
| 12 |
|
| 13 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 14 |
# dtype ๆ ๅฐ
|
|
@@ -102,7 +104,7 @@ def load_tensor_remote(
|
|
| 102 |
expected_elems = 1
|
| 103 |
for d in shape:
|
| 104 |
expected_elems *= d
|
| 105 |
-
|
| 106 |
f"[FETCH] {tensor_name}\n"
|
| 107 |
f" shape={shape} dtype={dtype_str}\n"
|
| 108 |
f" data_offsets={offsets}\n"
|
|
@@ -123,7 +125,7 @@ def load_tensor_remote(
|
|
| 123 |
|
| 124 |
# โโ ่ฐ่ฏ๏ผๆๅฐๅฎ้
ๆถๅฐ็ๅญ่ๆฐ โโโโโโโโโโโโโโโโ
|
| 125 |
actual_bytes = len(r.content)
|
| 126 |
-
|
| 127 |
f" actual_bytes={actual_bytes} "
|
| 128 |
f"{'โ
' if actual_bytes == expected_bytes else 'โ ๅญ่ๆฐไธๅน้
!'}\n"
|
| 129 |
f" ๅ8ๅญ่(hex)={r.content[:8].hex()}\n"
|
|
@@ -139,7 +141,7 @@ def load_tensor_remote(
|
|
| 139 |
result = tensor.reshape(shape).float()
|
| 140 |
|
| 141 |
# โโ ่ฐ่ฏ๏ผๆๅฐ็ปๆ้ฆ่ก โโโโโโโโโโโโโโโโโโโโโโโโ
|
| 142 |
-
|
| 143 |
|
| 144 |
return result
|
| 145 |
|
|
|
|
| 9 |
import requests
|
| 10 |
import torch
|
| 11 |
from huggingface_hub import list_repo_files
|
| 12 |
+
from core.debug import dprint
|
| 13 |
+
|
| 14 |
|
| 15 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 16 |
# dtype ๆ ๅฐ
|
|
|
|
| 104 |
expected_elems = 1
|
| 105 |
for d in shape:
|
| 106 |
expected_elems *= d
|
| 107 |
+
dprint(
|
| 108 |
f"[FETCH] {tensor_name}\n"
|
| 109 |
f" shape={shape} dtype={dtype_str}\n"
|
| 110 |
f" data_offsets={offsets}\n"
|
|
|
|
| 125 |
|
| 126 |
# โโ ่ฐ่ฏ๏ผๆๅฐๅฎ้
ๆถๅฐ็ๅญ่ๆฐ โโโโโโโโโโโโโโโโ
|
| 127 |
actual_bytes = len(r.content)
|
| 128 |
+
dprint(
|
| 129 |
f" actual_bytes={actual_bytes} "
|
| 130 |
f"{'โ
' if actual_bytes == expected_bytes else 'โ ๅญ่ๆฐไธๅน้
!'}\n"
|
| 131 |
f" ๅ8ๅญ่(hex)={r.content[:8].hex()}\n"
|
|
|
|
| 141 |
result = tensor.reshape(shape).float()
|
| 142 |
|
| 143 |
# โโ ่ฐ่ฏ๏ผๆๅฐ็ปๆ้ฆ่ก โโโโโโโโโโโโโโโโโโโโโโโโ
|
| 144 |
+
dprint(f" result[0,:5]={result[0,:5].tolist()}\n")
|
| 145 |
|
| 146 |
return result
|
| 147 |
|
|
@@ -3,6 +3,7 @@ import torch
|
|
| 3 |
import numpy as np
|
| 4 |
from scipy.stats import spearmanr
|
| 5 |
from core.layer_profile import LayerProfile
|
|
|
|
| 6 |
|
| 7 |
|
| 8 |
def pearson(a: torch.Tensor, b: torch.Tensor) -> float:
|
|
@@ -83,17 +84,16 @@ def analyze_layer(
|
|
| 83 |
lines: list[str] = []
|
| 84 |
|
| 85 |
# โโ ่ฐ่ฏ๏ผๆๅฐๆดไฝไฟกๆฏ + ๅๅงๆ้้ฆ่ก โโโโโโโโโโ
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
)
|
| 97 |
|
| 98 |
kv_tag = " [K=Vๅ
ฑไบซ]" if kv_shared else ""
|
| 99 |
lines.append(
|
|
@@ -121,13 +121,12 @@ def analyze_layer(
|
|
| 121 |
smxv, smnv, cond_v = sigma_stats(s_v)
|
| 122 |
|
| 123 |
# โโ ่ฐ่ฏ๏ผKVๅคดๅ็้ฆ่กๅๅงๆ้ โโโโโโโโโโโโโโ
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
f"k_t={list(k_t.shape)} "
|
| 127 |
-
f"s_kๅ5={[round(x,4) for x in s_k[:5].tolist()]}
|
| 128 |
-
f"[DEBUG] KVๅคด{kv_h}: "
|
| 129 |
-
f"k_t[0,:10]={k_t[0, :10].tolist()}\n"
|
| 130 |
)
|
|
|
|
| 131 |
|
| 132 |
# KV ๆๆ
|
| 133 |
if kv_shared:
|
|
@@ -153,13 +152,12 @@ def analyze_layer(
|
|
| 153 |
smxq, smnq, cond_q = sigma_stats(s_q)
|
| 154 |
|
| 155 |
# โโ ่ฐ่ฏ๏ผQๅคดๅ็้ฆ่กๅๅงๆ้ โโโโโโโโโโโโ
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
f"q_t={list(q_t.shape)} "
|
| 159 |
-
f"s_qๅ5={[round(x,4) for x in s_q[:5].tolist()]}
|
| 160 |
-
f"[DEBUG] Qๅคด{h}: "
|
| 161 |
-
f"q_t[0,:10]={q_t[0, :10].tolist()}\n"
|
| 162 |
)
|
|
|
|
| 163 |
|
| 164 |
nqk = min(len(s_q), len(s_k))
|
| 165 |
nqv = min(len(s_q), len(s_v))
|
|
@@ -177,6 +175,13 @@ def analyze_layer(
|
|
| 177 |
cU_QV = cos_U(U_q, U_v)
|
| 178 |
cV_QV = cos_V(Vt_q, Vt_v)
|
| 179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
records.append({
|
| 181 |
"prefix": profile.prefix,
|
| 182 |
"layer": profile.layer_idx,
|
|
|
|
| 3 |
import numpy as np
|
| 4 |
from scipy.stats import spearmanr
|
| 5 |
from core.layer_profile import LayerProfile
|
| 6 |
+
from core.debug import dlog
|
| 7 |
|
| 8 |
|
| 9 |
def pearson(a: torch.Tensor, b: torch.Tensor) -> float:
|
|
|
|
| 84 |
lines: list[str] = []
|
| 85 |
|
| 86 |
# โโ ่ฐ่ฏ๏ผๆๅฐๆดไฝไฟกๆฏ + ๅๅงๆ้้ฆ่ก โโโโโโโโโโ
|
| 87 |
+
# โโ Debug๏ผๆดไฝไฟกๆฏ โโโโโโโโโโโโโโโโโโโโโโโ
|
| 88 |
+
dlog(lines, f"โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ")
|
| 89 |
+
dlog(lines, f"key_q = {profile.q.key}")
|
| 90 |
+
dlog(lines, f"key_k = {profile.k.key}")
|
| 91 |
+
dlog(lines, f"key_v = {profile.v.key if profile.v else 'K=V shared'}")
|
| 92 |
+
dlog(lines, f"W_q={list(W_q.shape)} W_k={list(W_k.shape)} W_v={list(W_v.shape)}")
|
| 93 |
+
dlog(lines, f"n_q={n_q} n_kv={n_kv} group={group} d_head={d_head} source={profile.head_dim_source}")
|
| 94 |
+
dlog(lines, f"W_k[0,:10] = {W_k[0, :10].tolist()}")
|
| 95 |
+
dlog(lines, f"W_q[0,:10] = {W_q[0, :10].tolist()}")
|
| 96 |
+
dlog(lines, f"โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ")
|
|
|
|
| 97 |
|
| 98 |
kv_tag = " [K=Vๅ
ฑไบซ]" if kv_shared else ""
|
| 99 |
lines.append(
|
|
|
|
| 121 |
smxv, smnv, cond_v = sigma_stats(s_v)
|
| 122 |
|
| 123 |
# โโ ่ฐ่ฏ๏ผKVๅคดๅ็้ฆ่กๅๅงๆ้ โโโโโโโโโโโโโโ
|
| 124 |
+
# โโ Debug๏ผKV ๅคด โโโโโโโโโโโโโโโโโโโโโโ
|
| 125 |
+
dlog(lines,
|
| 126 |
+
f"KVๅคด{kv_h}: k_t={list(k_t.shape)} "
|
| 127 |
+
f"s_kๅ5={[round(x,4) for x in s_k[:5].tolist()]}"
|
|
|
|
|
|
|
| 128 |
)
|
| 129 |
+
dlog(lines, f"KVๅคด{kv_h}: k_t[0,:10]={k_t[0, :10].tolist()}")
|
| 130 |
|
| 131 |
# KV ๆๆ
|
| 132 |
if kv_shared:
|
|
|
|
| 152 |
smxq, smnq, cond_q = sigma_stats(s_q)
|
| 153 |
|
| 154 |
# โโ ่ฐ่ฏ๏ผQๅคดๅ็้ฆ่กๅๅงๆ้ โโโโโโโโโโโโ
|
| 155 |
+
# โโ Debug๏ผQ ๅคด โโโโโโโโโโโโโโโโโโโ
|
| 156 |
+
dlog(lines,
|
| 157 |
+
f" Qๅคด{h}: q_t={list(q_t.shape)} "
|
| 158 |
+
f"s_qๅ5={[round(x,4) for x in s_q[:5].tolist()]}"
|
|
|
|
|
|
|
| 159 |
)
|
| 160 |
+
dlog(lines, f" Qๅคด{h}: q_t[0,:10]={q_t[0, :10].tolist()}")
|
| 161 |
|
| 162 |
nqk = min(len(s_q), len(s_k))
|
| 163 |
nqv = min(len(s_q), len(s_v))
|
|
|
|
| 175 |
cU_QV = cos_U(U_q, U_v)
|
| 176 |
cV_QV = cos_V(Vt_q, Vt_v)
|
| 177 |
|
| 178 |
+
# โโ Debug๏ผๅ
ณ้ฎๆๆ โโโโโโโโโโโโโโโ
|
| 179 |
+
dlog(lines,
|
| 180 |
+
f" Qๅคด{h}: pearson={pqk:+.4f} "
|
| 181 |
+
f"alpha_QK={a_qk:.4f} "
|
| 182 |
+
f"s_q[0]={s_q[0]:.4f} s_k[0]={s_k[0]:.4f}"
|
| 183 |
+
)
|
| 184 |
+
|
| 185 |
records.append({
|
| 186 |
"prefix": profile.prefix,
|
| 187 |
"layer": profile.layer_idx,
|
|
@@ -11,6 +11,7 @@ import gradio as gr
|
|
| 11 |
import requests
|
| 12 |
import pandas as pd
|
| 13 |
import numpy as np
|
|
|
|
| 14 |
|
| 15 |
from core.fetcher import (
|
| 16 |
load_all_shard_headers,
|
|
@@ -175,6 +176,16 @@ def run_analysis(
|
|
| 175 |
q_hdr, q_hs = all_headers[prof.q.shard]
|
| 176 |
k_hdr, k_hs = all_headers[prof.k.shard]
|
| 177 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
W_q = load_tensor_remote(q_url, prof.q.key, q_hdr, q_hs, token)
|
| 179 |
W_k = load_tensor_remote(k_url, prof.k.key, k_hdr, k_hs, token)
|
| 180 |
|
|
|
|
| 11 |
import requests
|
| 12 |
import pandas as pd
|
| 13 |
import numpy as np
|
| 14 |
+
from core.debug import dlog
|
| 15 |
|
| 16 |
from core.fetcher import (
|
| 17 |
load_all_shard_headers,
|
|
|
|
| 176 |
q_hdr, q_hs = all_headers[prof.q.shard]
|
| 177 |
k_hdr, k_hs = all_headers[prof.k.shard]
|
| 178 |
|
| 179 |
+
dlog(log,
|
| 180 |
+
f"Layer {idx}:\n"
|
| 181 |
+
f" q: {prof.q.shard} โ {prof.q.key}\n"
|
| 182 |
+
f" k: {prof.k.shard} โ {prof.k.key}\n"
|
| 183 |
+
f" v: {prof.v.shard + ' โ ' + prof.v.key if prof.v else 'K=V shared'}\n"
|
| 184 |
+
f" k_header_size={k_hs}\n"
|
| 185 |
+
f" k_offsets={k_hdr[prof.k.key]['data_offsets']}\n"
|
| 186 |
+
f" k_abs_start={8 + k_hs + k_hdr[prof.k.key]['data_offsets'][0]}"
|
| 187 |
+
)
|
| 188 |
+
|
| 189 |
W_q = load_tensor_remote(q_url, prof.q.key, q_hdr, q_hs, token)
|
| 190 |
W_k = load_tensor_remote(k_url, prof.k.key, k_hdr, k_hs, token)
|
| 191 |
|