mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
feat(sdnq): auto-name and default-save benchmark outputs
Write the text and json reports by default, named to the archive convention <gpu>-t<torch>-<date> with a collision suffix for the pair, into $SDNQ_BENCH_DIR, --outdir, or benchmarks/ under the sdnext root. 'none' disables either output and explicit paths behave as before.
This commit is contained in:
@@ -50,6 +50,7 @@ package-lock.json
|
||||
/outputs/**/*
|
||||
/models/**/*
|
||||
/tmp
|
||||
/benchmarks
|
||||
.*/
|
||||
cache
|
||||
tunableop_results*.csv
|
||||
|
||||
@@ -289,8 +289,9 @@ def parse_cli():
|
||||
parser.add_argument("--skip-bench", action="store_true", help="skip benchmarks, run checks and the fp8 and compile probes only")
|
||||
parser.add_argument("--dtype", type=str, default="auto", choices=["auto", "bf16", "fp16"], help="tensor dtype for benchmarks; auto uses the dtype the webui selected for this gpu (default: %(default)s)")
|
||||
parser.add_argument("--config-timeout", type=int, default=300, help="best effort: abort a config whose compile plus first call exceeds this many seconds, 0 disables; cannot interrupt native-level hangs (default: %(default)s)")
|
||||
parser.add_argument("--save", type=str, default=None, help="write a plain-text copy of all tables and notes to this file; keeps colors and live progress on the terminal, unlike piping through tee")
|
||||
parser.add_argument("--json", type=str, default=None, help="write structured results (environment, probes, per-shape and dequant timings, recommendations) to this file")
|
||||
parser.add_argument("--save", type=str, default="auto", help="plain-text copy of all tables and notes; 'auto' (default) names it <gpu>-t<torch>-<date>.txt in the output directory, 'none' disables, anything else is used as the path")
|
||||
parser.add_argument("--json", type=str, default="auto", help="structured results (environment, probes, per-shape and dequant timings, recommendations); 'auto' (default) names it <gpu>-t<torch>-<date>.json in the output directory, 'none' disables, anything else is used as the path")
|
||||
parser.add_argument("--outdir", type=str, default=None, help="directory for auto-named outputs (default: $SDNQ_BENCH_DIR, or benchmarks/ under the sdnext root)")
|
||||
args = parser.parse_args()
|
||||
sys.argv = sys.argv[:1] # sdnext parses argv again on import and rejects unknown arguments
|
||||
return args
|
||||
@@ -868,6 +869,36 @@ def print_environment(fp8_result, prep_status, prep_detail, weight_dequant_resul
|
||||
)
|
||||
|
||||
|
||||
def resolve_output_paths(args):
|
||||
# auto outputs follow the archive convention <gpu>-t<torch major.minor>-<mondd>, one
|
||||
# stem shared by the txt/json pair, suffixed -2, -3... when the pair already exists
|
||||
args.save = None if str(args.save).strip().lower() in {"none", ""} else args.save
|
||||
args.json = None if str(args.json).strip().lower() in {"none", ""} else args.json
|
||||
if args.save != "auto" and args.json != "auto":
|
||||
return
|
||||
try:
|
||||
gpu = torch_device_module.get_device_name(torch.device(torch_device))
|
||||
except Exception:
|
||||
gpu = "gpu"
|
||||
drop = {"nvidia", "geforce", "rtx", "gtx", "amd", "radeon", "rx", "intel", "arc", "graphics", "apple", "laptop", "gpu"}
|
||||
tokens = ["".join(ch for ch in token if ch.isalnum()) for token in gpu.lower().replace("(r)", " ").replace("(tm)", " ").split()]
|
||||
tokens = [token for token in tokens if token and token not in drop]
|
||||
gpu_id = "".join(tokens) or "gpu"
|
||||
torch_digits = "".join(str(torch.__version__).split("+", maxsplit=1)[0].split(".")[:2])
|
||||
stem = f"{gpu_id}-t{torch_digits}-{time.strftime('%b%d').lower()}"
|
||||
outdir = args.outdir or os.environ.get("SDNQ_BENCH_DIR", None) or os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "benchmarks")
|
||||
outdir = os.path.expanduser(outdir)
|
||||
os.makedirs(outdir, exist_ok=True)
|
||||
candidate, counter = stem, 1
|
||||
while os.path.exists(os.path.join(outdir, f"{candidate}.txt")) or os.path.exists(os.path.join(outdir, f"{candidate}.json")):
|
||||
counter += 1
|
||||
candidate = f"{stem}-{counter}"
|
||||
if args.save == "auto":
|
||||
args.save = os.path.join(outdir, f"{candidate}.txt")
|
||||
if args.json == "auto":
|
||||
args.json = os.path.join(outdir, f"{candidate}.json")
|
||||
|
||||
|
||||
def print_banner(selected, sections, args):
|
||||
lines = [
|
||||
"measures sdnq attention and weight dequantization speed and accuracy on this gpu and recommends values for [cyan]Compute Settings -> SDNQ / SDNQ Attention[/cyan]",
|
||||
@@ -3516,6 +3547,7 @@ def main():
|
||||
if unknown:
|
||||
console.print(f"[red]unknown shape preset(s): {', '.join(unknown)}; available: {', '.join(shape_presets)}[/red]")
|
||||
sys.exit(1)
|
||||
resolve_output_paths(args)
|
||||
global pending_outputs # pylint: disable=global-statement
|
||||
pending_outputs = dict(save=args.save, json=args.json, args=args, sections=sections, selected=selected)
|
||||
print_banner(selected, sections, args)
|
||||
|
||||
Reference in New Issue
Block a user