Spaces:
Running on Zero
Running on Zero
File size: 7,891 Bytes
d174adb 5019f50 169cfd5 5019f50 9b1dd0a 5019f50 d174adb 9b1dd0a d174adb 169cfd5 d174adb 5019f50 01331b0 5019f50 d174adb b9fb981 d174adb 169cfd5 01331b0 5019f50 9b1dd0a b9fb981 d174adb 5019f50 d174adb 5019f50 d174adb 5019f50 169cfd5 d174adb 5019f50 d174adb 5019f50 169cfd5 d174adb 169cfd5 d174adb 5019f50 01331b0 5019f50 d174adb 169cfd5 01331b0 9b1dd0a d174adb 01331b0 d174adb 01331b0 9b1dd0a 01331b0 d174adb 9b1dd0a d174adb 5019f50 169cfd5 09375b4 169cfd5 9b1dd0a 420ac40 169cfd5 09375b4 169cfd5 09375b4 169cfd5 09375b4 5019f50 169cfd5 5019f50 d174adb 5019f50 d174adb 5019f50 169cfd5 5019f50 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | """Layer metadata and neuron detail loading with on-demand caching."""
import json
import os
from typing import Any, Dict, List, Optional, Tuple
from datasets import get_dataset_split_names, load_dataset
from config import QWEN25_DATASET_ROOT, REPO_ID, qwen25_dataset_path
# Config names and directories in the HF dataset
CONFIG_META = f"{QWEN25_DATASET_ROOT}_meta_data"
CONFIG_DETAILS = f"{QWEN25_DATASET_ROOT}_neuron_details"
# Global cache for per-layer meta dict (lightweight)
layer_meta_cache: Dict[int, Dict[int, Dict]] = {}
# Cache for per-layer, per-chunk neuron detail datasets (non-streaming)
# Keyed by layer_id -> chunk_start (every 1000 neurons) -> dataset split object
layer_datasets: Dict[int, Dict[int, Any]] = {}
# Cache for per-neuron detailed rows (only selected neuron)
neuron_detail_cache: Dict[Tuple[int, int], Dict] = {}
def _summarize_splits(split_names: List[str], head: int = 5, tail: int = 5) -> str:
if not split_names:
return "[]"
if len(split_names) <= head + tail:
return str(split_names)
return str(split_names[:head] + ["..."] + split_names[-tail:])
def load_layer_options() -> List[int]:
"""Fetch available layer IDs, prefer local JSON, fallback to default."""
try:
if os.path.exists("resources/layer_list.json"):
with open("resources/layer_list.json", "r", encoding="utf-8") as f:
layer_options = json.load(f)
layer_options = sorted(int(x) for x in layer_options)
else:
layer_options = [20]
print(f"[info] Available layer IDs: {layer_options}")
return layer_options
except Exception as e: # pragma: no cover - small utility
print(f"[error] Failed to load layer options: {e}")
return [20]
def load_layer_data(layer_id: int) -> Dict[int, Dict]:
"""Load lightweight meta data for a specific layer from HF dataset.
Uses a single-file data_files load for layer meta parquet.
Only minimal fields are stored; heavy refs are not loaded here.
"""
if layer_id in layer_meta_cache:
cached = layer_meta_cache[layer_id]
print(f"[info] Using cached meta_data for layer {layer_id} (size={len(cached)})")
return cached
try:
data_file = qwen25_dataset_path(
f"meta_data/layer_{layer_id}-00000-of-00001.parquet"
)
print(f"[info] Loading meta_data via data_files: layer={layer_id} file={data_file}")
ds = load_dataset(
REPO_ID,
data_files={"train": [data_file]},
split="train",
streaming=False,
)
print(f"[info] meta_data loaded: file={data_file} rows={len(ds)}")
meta_fields = {
"neuron_id",
"modality",
"vision_summary",
"language_summary",
"consistency_score",
"miou",
}
meta_dict: Dict[int, Dict] = {}
for item in ds:
nid = item.get("neuron_id")
if nid is None:
continue
try:
meta = {k: item.get(k) for k in meta_fields}
meta_dict[int(nid)] = meta
except Exception as row_err: # pragma: no cover
print(f"[warn] Skipping meta row for layer {layer_id}: {row_err}")
layer_meta_cache[layer_id] = meta_dict
print(f"[info] Loaded meta_data for {len(meta_dict)} neurons for layer {layer_id}")
return meta_dict
except Exception as e: # pragma: no cover - network/cache dependent
print(f"[error] Failed to load meta_data for layer {layer_id}: {e}")
return {}
def _details_split_name(layer_id: int, neuron_id: int, chunk: int = 1000) -> str:
start = (int(neuron_id) // chunk) * chunk
end = start + (chunk - 1)
return f"layer_{layer_id}_neuron_{start:06d}_{end:06d}"
def load_neuron_detail(layer_id: int, neuron_id: int) -> Optional[Dict]:
"""Load detailed refs (vision/text) for the selected neuron only.
The dataset index now aligns with the neuron index, including empty neurons,
so we can directly index into the split without an extra scan on `neuron_id`.
"""
cache_key = (int(layer_id), int(neuron_id))
if cache_key in neuron_detail_cache:
print(f"[info] Using cached neuron_details for neuron {neuron_id} layer {layer_id}")
return neuron_detail_cache[cache_key]
# Ensure meta exists (for sanity), but don't depend on its split info
meta_dict = load_layer_data(int(layer_id))
if int(neuron_id) not in meta_dict:
return None
chunk_size = 1000
split_name = _details_split_name(int(layer_id), int(neuron_id), chunk=chunk_size)
print(f"[info] Loading neuron_details: layer={layer_id} neuron={neuron_id} split={split_name}")
split_names = None
try:
split_names = get_dataset_split_names(path=REPO_ID, config_name=CONFIG_DETAILS)
print(
f"[info] neuron_details splits via config='{CONFIG_DETAILS}': count={len(split_names)} "
f"sample={_summarize_splits(split_names)}"
)
except Exception as e:
print(
f"[warn] Failed to list neuron_details splits via config: {e}; "
"trying the expected file directly..."
)
if split_names is not None and split_name not in split_names:
print(f"[warn] neuron_details split '{split_name}' not found for layer {layer_id}")
return None
try:
chunk_start = (int(neuron_id) // chunk_size) * chunk_size
layer_cache = layer_datasets.setdefault(int(layer_id), {})
if chunk_start in layer_cache:
ds = layer_cache[chunk_start]
print(
f"[info] Using cached neuron_details split='{split_name}' for layer {layer_id} "
f"chunk_start={chunk_start}"
)
else:
data_file = qwen25_dataset_path(
f"neuron_details/layer_{layer_id}/{split_name}-00000-of-00001.parquet"
)
print(
f"[info] Loading neuron_details via data_files: layer={layer_id} split={split_name} "
f"file={data_file}"
)
ds = load_dataset(
REPO_ID,
data_files={"train": [data_file]},
split="train",
streaming=False,
)
layer_cache[chunk_start] = ds
print(f"[info] Cached split='{split_name}' rows={len(ds)} for layer {layer_id}")
# Dataset index matches neuron index; empty neurons yield empty rows.
local_index = int(neuron_id) - chunk_start
if local_index < 0 or local_index >= len(ds):
print(
f"[warn] Neuron {neuron_id} maps to local index {local_index}, "
f"but split '{split_name}' has length {len(ds)}"
)
return None
row = ds[int(local_index)]
neuron_detail_cache[cache_key] = row
print(f"[info] Loaded neuron_details for neuron {neuron_id} layer {layer_id} via direct index")
return row
except Exception as e: # pragma: no cover - network/cache dependent
print(f"[error] Failed to load neuron_details for neuron {neuron_id} layer {layer_id}: {e}")
return None
def get_neuron_ids(layer_id: int) -> List[int]:
"""Return all neuron IDs for the given layer from meta_data."""
data = load_layer_data(layer_id)
if data:
return sorted(data.keys())
return []
def get_consistency_neurons(layer_id: int, max_examples: int = 25) -> List[int]:
"""Return up to max_examples neurons with consistency_score == 1 from meta_data."""
data = load_layer_data(layer_id)
if not data:
return []
matches = [nid for nid, meta in data.items() if meta.get("consistency_score") == 1.0]
return sorted(matches)[:max_examples]
|