11#!/usr/bin/env python3
22import os
3+ import re
34import sys
45import json
56from pathlib import Path
@@ -60,18 +61,44 @@ def detect_eval_jsons(d: Path) -> Tuple[Optional[Path], Optional[Path]]:
6061
6162def parse_pretty_env (pretty_env : str ) -> str :
6263 try :
63- lines = [l for l in pretty_env .splitlines () if l .startswith ('GPU ' )]
64+ # Only match lines like "GPU 0: <name>", avoid headers like "GPU models and configuration:"
65+ lines = [l for l in pretty_env .splitlines () if re .match (r'^GPU\s+\d+\s*:' , l )]
6466 names = [l .split (':' , 1 )[1 ].strip () for l in lines ]
6567 if not names :
6668 return 'Unknown GPU'
67- # Compress identical names (roughly)
68- from collections import Counter
69- c = Counter (names )
70- return ' + ' .join ([f"{ n } × { name } " for name , n in c .items ()])
69+ # Unique GPU names (no counts), order preserved
70+ seen = []
71+ for n in names :
72+ if n not in seen :
73+ seen .append (n )
74+ return ' + ' .join (seen ) if seen else 'Unknown GPU'
7175 except Exception :
7276 return 'Unknown GPU'
7377
7478
79+ def derive_lens_and_conc (dir_name : str , exp_name_hint : str ) -> Tuple [Optional [int ], Optional [int ], Optional [int ]]:
80+ """Extract (isl, osl, conc) from artifact directory name or exp_name hint.
81+
82+ Expected patterns inside `dir_name` (or `exp_name_hint`):
83+ - "<num>k<num>k" for (ISL, OSL) where k -> 1024
84+ - "_conc<num>_" for concurrency
85+ """
86+ isl = osl = conc = None
87+ try :
88+ m = re .search (r'(\d+)k(\d+)k' , dir_name )
89+ if not m and exp_name_hint :
90+ m = re .search (r'(\d+)k(\d+)k' , exp_name_hint )
91+ if m :
92+ isl = int (m .group (1 )) * 1024
93+ osl = int (m .group (2 )) * 1024
94+ c = re .search (r'_conc(\d+)(?:_|$)' , dir_name )
95+ if c :
96+ conc = int (c .group (1 ))
97+ except Exception :
98+ pass
99+ return isl , osl , conc
100+
101+
75102def extract_lm_metrics (json_path : Path , task : Optional [str ] = None ) -> Dict [str , Any ]:
76103 data = load_json (json_path ) or {}
77104 results = data .get ('results' ) or {}
@@ -179,6 +206,7 @@ def main():
179206 rows : List [Dict [str , Any ]] = []
180207 for d in find_eval_sets (root ):
181208 meta = load_json (d / 'meta_env.json' ) or {}
209+ isl , osl , conc = derive_lens_and_conc (d .name , exp_name )
182210 lm_path , le_path = detect_eval_jsons (d )
183211 # Prefer lm-eval when available, else lighteval
184212 if lm_path :
@@ -196,6 +224,9 @@ def main():
196224 'precision' : (meta .get ('precision' ) or 'unknown' ).lower (),
197225 'tp' : int (meta .get ('tp' ) or 1 ),
198226 'ep' : int (meta .get ('ep' ) or 1 ),
227+ 'conc' : int (conc ) if conc is not None else None ,
228+ 'isl' : int (isl ) if isl is not None else None ,
229+ 'osl' : int (osl ) if osl is not None else None ,
199230 'dp_attention' : str (meta .get ('dp_attention' ) or 'false' ),
200231 'task' : m .get ('task' ) or 'unknown' ,
201232 'em_strict' : m .get ('strict' ),
@@ -214,8 +245,8 @@ def main():
214245 print ('> No eval results found to summarize.' )
215246 else :
216247 # Print Markdown summary table
217- print ('| Model | Hardware | Framework | Precision | TP | EP | DPA | Task | EM Strict | EM Flexible | N (eff) |' )
218- print ('| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |' )
248+ print ('| Model | Hardware | Framework | Precision | TP | EP | Conc | ISL | OSL | DPA | Task | EM Strict | EM Flexible | N (eff) |' )
249+ print ('| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | ' )
219250 for r in rows :
220251 print (
221252 f"| { r ['model' ]} "
@@ -224,6 +255,9 @@ def main():
224255 f"| { r ['precision' ].upper ()} "
225256 f"| { r ['tp' ]} "
226257 f"| { r ['ep' ]} "
258+ f"| { r .get ('conc' ,'' )} "
259+ f"| { r .get ('isl' ,'' )} "
260+ f"| { r .get ('osl' ,'' )} "
227261 f"| { r ['dp_attention' ]} "
228262 f"| { r ['task' ]} "
229263 f"| { pct (r ['em_strict' ])} { se (r ['em_strict_se' ])} "
0 commit comments