Alex W. commited on
Commit
8d21309
·
1 Parent(s): c1b6928

refactor(ui): translate tab_inspect.py to English

Browse files

Convert all user-facing text in Tab1 from Chinese to English.
Logic, function signatures, and variable names unchanged.

- "推荐模型" → "Recommended Models"
- "层号说明" → "Layer Index"
- "不按组件重排,原始值直接输出"
→ "Raw index, not re-numbered per component"
- Example tables: column headers and annotations translated

- "🔬 结构探测:" → "🔬 Structure Inspection:"
- "【量化检测】" → "[Quantization Check]"
- "📋 config:" → "📋 Config:"
- "📦 shard 数:" → "📦 Shards:"
- "⚠️ 未发现 Q/K/V 层,前30个 key:"
→ "⚠️ No Q/K/V layers found. First 30 keys:"
- "config.json 读取失败:" → "Could not read config.json:"
- "读取失败:" → "Failed to load headers:"

- Tab title: "🔬 结构探测" → "🔬 Inspect"
- Markdown description: translated; added note:
"No weights are downloaded — structure is inferred from
safetensors headers only."
- Model ID label: "HuggingFace 模型 ID" → "HuggingFace Model ID"
- Token label: "公开模型可留空" → "leave empty for public models"
- Button: "🔍 探测结构" → "🔍 Inspect Structure"
- Log textbox label: "结构探测日志" → "Inspection Log"
- Table label: "层结构概览表" → "Layer Structure Overview"
- progress desc: "完成" → "Done"

- Function signatures, variable names, return types
- All logic and data flow
- summarize_structure() output (lives in core/layer_profile.py)

Files changed (1) hide show
  1. ui/tab_inspect.py +62 -60
ui/tab_inspect.py CHANGED
@@ -1,9 +1,9 @@
1
  # ui/tab_inspect.py
2
  """
3
- Tab1:模型结构探测
4
- - 读取所有 shard header
5
- - 展示原始 key 结构
6
- - 自动构建 LayerProfile 并展示推断结果
7
  """
8
 
9
  import gradio as gr
@@ -23,35 +23,36 @@ from core.layer_profile import (
23
  )
24
 
25
  SIDEBAR_MD = """
26
- ### ✅ 推荐模型
27
  google/gemma-4-e2b
28
  google/gemma-4-e4b-it
29
  google/gemma-4-31b-it
30
  Qwen/Qwen2.5-14B-Instruct
31
  deepseek-ai/DeepSeek-R1-Distill-Qwen-14B
32
- meta-llama/Meta-Llama-3-8B
33
-
34
-
35
- ### 层号说明
36
- - 层号 = safetensors key 中 `layers.{N}` 的 **N**
37
- - **不按组件重排**,原始值直接输出
38
- - 混合模态模型(如 Gemma-4):
39
- - `layers.0~11` 同时含 audio/vision/text
40
- - 全部输出,按前缀区分组件
41
-
42
- ### 示例:Gemma-4-E2B
43
- | 组件 | 层范围 |
44
- |------|--------|
45
- | audio_tower | 0~11 |
46
- | language_model | 0~34 |
47
- | vision_tower | 0~15 |
48
-
49
- ### 示例:Gemma-4-31B
50
- | 组件 | 层范围 |
51
- |------|--------|
52
- | language(局部层) | 0~59 |
53
- | language(全局层) | 5,11,17...59 |
54
- | vision_tower | 0~26 |
 
55
  """
56
 
57
 
@@ -61,23 +62,23 @@ def inspect_model(
61
  progress=gr.Progress()
62
  ) -> tuple[str, pd.DataFrame]:
63
  """
64
- 返回 (结构文本日志, 组件概览DataFrame)
65
  """
66
  if not model_id.strip():
67
- return "❌ 请输入模型 ID", None
68
 
69
  token = hf_token.strip() or None
70
- log = [f"🔬 结构探测:{model_id}\n{'═'*80}\n"]
71
 
72
- # ── 量化检测 ─────────────────────────────────
73
- progress(0.05, desc="量化检测...")
74
  blocked, qmsg = check_quantization(model_id, token)
75
- log.append(f"【量化检测】\n{qmsg}\n{'─'*80}\n")
76
  if blocked:
77
  return "".join(log), None
78
 
79
- # ── config.json ───────────────────────────────
80
- progress(0.10, desc="读取 config...")
81
  config_params = {}
82
  try:
83
  r = requests.get(
@@ -88,7 +89,7 @@ def inspect_model(
88
  if r.status_code == 200:
89
  config_params = extract_config_params(r.json())
90
  log.append(
91
- f"📋 config:\n"
92
  f" model_type = {config_params.get('model_type')}\n"
93
  f" hidden = {config_params.get('hidden_size')}\n"
94
  f" n_heads = {config_params.get('num_attention_heads')}\n"
@@ -97,45 +98,44 @@ def inspect_model(
97
  f"{'─'*80}\n"
98
  )
99
  except Exception as e:
100
- log.append(f"⚠️ config.json 读取失败:{e}\n")
101
 
102
- # ── 读取所有 shard headers ────────────────────
103
- progress(0.20, desc="读取 shard headers...")
104
  try:
105
  all_headers = load_all_shard_headers(model_id, token)
106
  except requests.exceptions.HTTPError as e:
107
  return http_error_msg(e, model_id), None
108
  except Exception as e:
109
- return "".join(log) + f"❌ 读取失败:{e}\n", None
110
 
111
  total_keys = sum(len(h) for h, _ in all_headers.values())
112
  log.append(
113
- f"📦 shard 数:{len(all_headers)} "
114
- f" key 数:{total_keys}\n"
115
  f"{'─'*80}\n"
116
  )
117
 
118
- # ── 扫描层结构 ────────────────────────────────
119
- progress(0.50, desc="扫描层结构...")
120
  profiles = scan_model_structure(all_headers, config_params)
121
 
122
  if not profiles:
123
- # 打印前30个 key 辅助调试
124
  sample = []
125
  for h, _ in list(all_headers.values())[:1]:
126
  sample = list(h.keys())[:30]
127
  return (
128
  "".join(log) +
129
- "⚠️ 未发现 Q/K/V 层,前30 key:\n" +
130
  "\n".join(sample), None
131
  )
132
 
133
- # ── 生成结构文本 ──────────────────────────────
134
- progress(0.80, desc="生成报告...")
135
  struct_text = summarize_structure(profiles)
136
  log.append(struct_text)
137
 
138
- # ── 生成概览 DataFrame ────────────────────────
139
  rows = []
140
  for (prefix, layer_idx), p in sorted(profiles.items()):
141
  rows.append({
@@ -155,43 +155,45 @@ def inspect_model(
155
 
156
  df = pd.DataFrame(rows)
157
 
158
- progress(1.0, desc="完成")
159
  return "".join(log), df
160
 
161
 
162
  # ─────────────────────────────────────────────
163
- # Tab1 UI 组件
164
  # ─────────────────────────────────────────────
165
 
166
  def build_tab_inspect():
167
- with gr.Tab("🔬 结构探测"):
168
  gr.Markdown("""
169
- **第一步:先探测模型结构**,自动识别组件、head_dimK=V共享层。
170
- 结果供「分析」Tab 使用。
 
 
171
  """)
172
 
173
  with gr.Row():
174
  with gr.Column(scale=3):
175
  inspect_model_id = gr.Textbox(
176
- label="HuggingFace 模型 ID",
177
  placeholder="google/gemma-4-e2b",
178
  value="google/gemma-4-e2b"
179
  )
180
  inspect_token = gr.Textbox(
181
- label="HF Access Token(公开模型可留空)",
182
  type="password"
183
  )
184
- inspect_btn = gr.Button("🔍 探测结构", variant="secondary")
185
 
186
  with gr.Column(scale=1):
187
  gr.Markdown(SIDEBAR_MD)
188
 
189
  inspect_log = gr.Textbox(
190
- label="结构探测日志",
191
  lines=30, max_lines=200
192
  )
193
  inspect_table = gr.Dataframe(
194
- label="层结构概览表",
195
  headers=[
196
  "prefix", "layer", "d_model", "head_dim", "dim_source",
197
  "n_q", "n_kv", "kv_shared", "complete",
 
1
  # ui/tab_inspect.py
2
  """
3
+ Tab1: Model Structure Inspection
4
+ - Read all shard headers
5
+ - Display raw key structure
6
+ - Auto-build LayerProfile and display inferred results
7
  """
8
 
9
  import gradio as gr
 
23
  )
24
 
25
  SIDEBAR_MD = """
26
+ ### ✅ Recommended Models
27
  google/gemma-4-e2b
28
  google/gemma-4-e4b-it
29
  google/gemma-4-31b-it
30
  Qwen/Qwen2.5-14B-Instruct
31
  deepseek-ai/DeepSeek-R1-Distill-Qwen-14B
32
+ meta-llama/Meta-Llama-3-8B (Need access right)
33
+
34
+ ---
35
+
36
+ ### Layer Index
37
+ - Layer index = **N** in `layers.{N}` of safetensors keys
38
+ - Raw index, **not re-numbered per component**
39
+ - Multi-modal models (e.g. Gemma-4):
40
+ - `layers.0~11` may contain audio / vision / text layers
41
+ - All components output separately, distinguished by prefix
42
+
43
+ ### Example: Gemma-4-E2B
44
+ | Component | Layer Range |
45
+ |-----------|-------------|
46
+ | audio_tower | 0 ~ 11 |
47
+ | language_model | 0 ~ 34 |
48
+ | vision_tower | 0 ~ 15 |
49
+
50
+ ### Example: Gemma-4-31B
51
+ | Component | Layer Range |
52
+ |-----------|-------------|
53
+ | language (local) | 0 ~ 59 |
54
+ | language (global) | 5, 11, 17 … 59 |
55
+ | vision_tower | 0 ~ 26 |
56
  """
57
 
58
 
 
62
  progress=gr.Progress()
63
  ) -> tuple[str, pd.DataFrame]:
64
  """
65
+ Returns (inspection log text, layer structure DataFrame)
66
  """
67
  if not model_id.strip():
68
+ return "❌ Please enter a model ID.", None
69
 
70
  token = hf_token.strip() or None
71
+ log = [f"🔬 Structure Inspection: {model_id}\n{'═'*80}\n"]
72
 
73
+ # ── Quantization check ────────────────────────────────────────────────────
74
+ progress(0.05, desc="Checking quantization...")
75
  blocked, qmsg = check_quantization(model_id, token)
76
+ log.append(f"[Quantization Check]\n{qmsg}\n{'─'*80}\n")
77
  if blocked:
78
  return "".join(log), None
79
 
80
+ # ── config.json ───────────────────────────────────────────────────────────
81
+ progress(0.10, desc="Reading config...")
82
  config_params = {}
83
  try:
84
  r = requests.get(
 
89
  if r.status_code == 200:
90
  config_params = extract_config_params(r.json())
91
  log.append(
92
+ f"📋 Config:\n"
93
  f" model_type = {config_params.get('model_type')}\n"
94
  f" hidden = {config_params.get('hidden_size')}\n"
95
  f" n_heads = {config_params.get('num_attention_heads')}\n"
 
98
  f"{'─'*80}\n"
99
  )
100
  except Exception as e:
101
+ log.append(f"⚠️ Could not read config.json: {e}\n")
102
 
103
+ # ── Load all shard headers ─────────────────────────────────────────────────
104
+ progress(0.20, desc="Loading shard headers...")
105
  try:
106
  all_headers = load_all_shard_headers(model_id, token)
107
  except requests.exceptions.HTTPError as e:
108
  return http_error_msg(e, model_id), None
109
  except Exception as e:
110
+ return "".join(log) + f"❌ Failed to load headers: {e}\n", None
111
 
112
  total_keys = sum(len(h) for h, _ in all_headers.values())
113
  log.append(
114
+ f"📦 Shards: {len(all_headers)} "
115
+ f"Total keys: {total_keys}\n"
116
  f"{'─'*80}\n"
117
  )
118
 
119
+ # ── Scan layer structure ───────────────────────────────────────────────────
120
+ progress(0.50, desc="Scanning layer structure...")
121
  profiles = scan_model_structure(all_headers, config_params)
122
 
123
  if not profiles:
 
124
  sample = []
125
  for h, _ in list(all_headers.values())[:1]:
126
  sample = list(h.keys())[:30]
127
  return (
128
  "".join(log) +
129
+ "⚠️ No Q/K/V layers found. First 30 keys:\n" +
130
  "\n".join(sample), None
131
  )
132
 
133
+ # ── Generate structure text ────────────────────────────────────────────────
134
+ progress(0.80, desc="Generating report...")
135
  struct_text = summarize_structure(profiles)
136
  log.append(struct_text)
137
 
138
+ # ── Build overview DataFrame ───────────────────────────────────────────────
139
  rows = []
140
  for (prefix, layer_idx), p in sorted(profiles.items()):
141
  rows.append({
 
155
 
156
  df = pd.DataFrame(rows)
157
 
158
+ progress(1.0, desc="Done")
159
  return "".join(log), df
160
 
161
 
162
  # ─────────────────────────────────────────────
163
+ # Tab1 UI
164
  # ─────────────────────────────────────────────
165
 
166
  def build_tab_inspect():
167
+ with gr.Tab("🔬 Inspect"):
168
  gr.Markdown("""
169
+ **Step 1: Inspect model structure** — auto-detect components, head_dim, and K=V shared layers.
170
+ Results are used by the **Analyze** tab.
171
+
172
+ > No weights are downloaded — structure is inferred from safetensors headers only.
173
  """)
174
 
175
  with gr.Row():
176
  with gr.Column(scale=3):
177
  inspect_model_id = gr.Textbox(
178
+ label="HuggingFace Model ID",
179
  placeholder="google/gemma-4-e2b",
180
  value="google/gemma-4-e2b"
181
  )
182
  inspect_token = gr.Textbox(
183
+ label="HF Access Token (leave empty for public models)",
184
  type="password"
185
  )
186
+ inspect_btn = gr.Button("🔍 Inspect Structure", variant="secondary")
187
 
188
  with gr.Column(scale=1):
189
  gr.Markdown(SIDEBAR_MD)
190
 
191
  inspect_log = gr.Textbox(
192
+ label="Inspection Log",
193
  lines=30, max_lines=200
194
  )
195
  inspect_table = gr.Dataframe(
196
+ label="Layer Structure Overview",
197
  headers=[
198
  "prefix", "layer", "d_model", "head_dim", "dim_source",
199
  "n_q", "n_kv", "kv_shared", "complete",