(rows: List[Dict[str, Any]], args: argparse.Namespace, model_load_seconds: float)
| 143 | |
| 144 | |
| 145 | def markdown_summary(rows: List[Dict[str, Any]], args: argparse.Namespace, model_load_seconds: float) -> str: |
| 146 | successful = [row for row in rows if not row.get("error")] |
| 147 | failed = [row for row in rows if row.get("error")] |
| 148 | known_audio = [row for row in successful if row.get("duration_seconds")] |
| 149 | total_audio = sum(float(row["duration_seconds"]) for row in known_audio) |
| 150 | total_elapsed = sum(float(row["elapsed_seconds"]) for row in successful) |
| 151 | throughput = total_audio / total_elapsed if total_audio and total_elapsed else None |
| 152 | meta = metadata_dict(args.metadata) |
| 153 | |
| 154 | lines = [ |
| 155 | "# FunASR Migration Benchmark Summary", |
| 156 | "", |
| 157 | "## Run configuration", |
| 158 | "", |
| 159 | f"- Input: `{args.input}`", |
| 160 | f"- Model: `{args.model}`", |
| 161 | f"- Device: `{args.device}`", |
| 162 | f"- VAD model: `{args.vad_model}`", |
| 163 | f"- Speaker model: `{args.spk_model or 'none'}`", |
| 164 | f"- Language: `{args.language}`", |
| 165 | f"- Batch size: `{args.batch_size}`", |
| 166 | f"- Model load seconds: `{model_load_seconds:.3f}`", |
| 167 | ] |
| 168 | for key, value in meta.items(): |
| 169 | lines.append(f"- {key}: `{value}`") |
| 170 | |
| 171 | lines.extend( |
| 172 | [ |
| 173 | "", |
| 174 | "## Aggregate results", |
| 175 | "", |
| 176 | f"- Files: `{len(rows)}`", |
| 177 | f"- Successful: `{len(successful)}`", |
| 178 | f"- Failed: `{len(failed)}`", |
| 179 | f"- Known audio seconds: `{total_audio:.3f}`" if known_audio else "- Known audio seconds: `unknown`", |
| 180 | f"- Inference seconds: `{total_elapsed:.3f}`" if successful else "- Inference seconds: `0.000`", |
| 181 | f"- Aggregate realtime factor: `{throughput:.3f}x`" if throughput else "- Aggregate realtime factor: `unknown`", |
| 182 | "", |
| 183 | "## Per-file results", |
| 184 | "", |
| 185 | "| File | Audio sec | Inference sec | RTF | Status | Text preview |", |
| 186 | "|---|---:|---:|---:|---|---|", |
| 187 | ] |
| 188 | ) |
| 189 | for row in rows: |
| 190 | duration = row.get("duration_seconds") |
| 191 | elapsed = row.get("elapsed_seconds") |
| 192 | rtf = row.get("realtime_factor") |
| 193 | status = "error" if row.get("error") else "ok" |
| 194 | preview = (row.get("text") or row.get("error") or "").replace("|", "\\|").replace("\n", " ")[:120] |
| 195 | lines.append( |
| 196 | "| {file} | {duration} | {elapsed} | {rtf} | {status} | {preview} |".format( |
| 197 | file=row["input"], |
| 198 | duration=f"{duration:.3f}" if isinstance(duration, (int, float)) else "", |
| 199 | elapsed=f"{elapsed:.3f}" if isinstance(elapsed, (int, float)) else "", |
| 200 | rtf=f"{rtf:.3f}x" if isinstance(rtf, (int, float)) else "", |
| 201 | status=status, |
| 202 | preview=preview, |
no test coverage detected
searching dependent graphs…