Download gui.py from CompressedGemma/HPC-Quantize-V2: direct link, hf CLI and curl.
- Browser
- Download file 65.6 kB
-
https://huggingface.co/CompressedGemma/HPC-Quantize-V2/resolve/main/gui.py
- Command line
-
hf download hf://CompressedGemma/HPC-Quantize-V2/gui.py
-
curl -L -o gui.py https://huggingface.co/CompressedGemma/HPC-Quantize-V2/resolve/main/gui.py
65.6 kB
| #!/usr/bin/env python3 | |
| """Graphical User Interface for HPC-Quantize V2 (Factored Q2_K Engine). | |
| Launch:: | |
| python3 gui.py | |
| Provides: | |
| * Source GGUF, iMatrix (.gguf / .dat), and Output (.gguf / .npz) file pickers | |
| * Interactive GGUF tensor table with live per-tensor status & RMSE updates | |
| * Real-time Telemetry Dashboard showing active tensor, current pipeline phase, | |
| dual progress bars (overall model + intra-tensor superblocks), throughput | |
| (blk/s), ETA, running RMSE, RMSE/sigma, Boltzmann temperature, and floor hits | |
| * Full HPCConfig controls (Geometry-Preserving Analogs, Coupled Bilinear Q2_K, | |
| Sieve + 36-state Viterbi, Spectral/Vesica/DC shaping, Candidate lattice size) | |
| * Timestamped verbose log stream with selectable verbosity level | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import datetime as dt | |
| import queue | |
| import shlex | |
| import threading | |
| import time | |
| import tkinter as tk | |
| from pathlib import Path | |
| from tkinter import filedialog, messagebox, ttk | |
| import numpy as np | |
| _HERE = Path(__file__).resolve().parent | |
| if not (_HERE / "hpc_quantize_v2").is_dir() and (_HERE / "__init__.py").is_file(): | |
| import importlib.util | |
| import sys | |
| if "hpc_quantize_v2" not in sys.modules: | |
| _spec = importlib.util.spec_from_file_location( | |
| "hpc_quantize_v2", | |
| _HERE / "__init__.py", | |
| submodule_search_locations=[str(_HERE)], | |
| ) | |
| if _spec is not None and _spec.loader is not None: | |
| _mod = importlib.util.module_from_spec(_spec) | |
| sys.modules["hpc_quantize_v2"] = _mod | |
| _spec.loader.exec_module(_mod) | |
| from hpc_quantize_v2 import ( | |
| GGUFReader, | |
| HPCConfig, | |
| Q1_0_BLOCK_BYTES, | |
| Q2KQuantizer, | |
| Q3_K_BLOCK_BYTES, | |
| QK1_0, | |
| QK3_K, | |
| QK4_0, | |
| QK_K, | |
| cuda_device_name, | |
| cuda_is_available, | |
| dequantize_q1_0_bytes, | |
| dequantize_q3_k_bytes, | |
| dequantize_q4_0_bytes, | |
| expand_importance, | |
| factor_only_solve, | |
| lookup_imatrix, | |
| quantize_tensor_q1_0, | |
| quantize_tensor_q3_k, | |
| quantize_tensor_q4_0, | |
| read_imatrix, | |
| ) | |
| from hpc_quantize_v2.gguf import ( | |
| is_q1_0_eligible, | |
| is_q2k_eligible, | |
| is_q3_k_eligible, | |
| is_q4_0_eligible, | |
| target_quant_type, | |
| tensor_type_key, | |
| write_quantized_gguf, | |
| ) | |
| from hpc_quantize_v2.reference import reference_solve, synthetic_cases | |
| DEFAULT_CUSTOM_RECIPE: dict[str, str] = { | |
| # Q4_0: quality-critical embeddings, attention, and SSM projections | |
| "token_embd": "Q4_0", | |
| "output": "Q4_0", | |
| "attn_gate": "Q4_0", | |
| "ssm_out": "Q4_0", | |
| "attn_q": "Q4_0", | |
| "attn_k": "Q4_0", | |
| "attn_v": "Q4_0", | |
| # Q1_0: the one tensor type that tolerates it well | |
| "attn_output": "Q1_0", | |
| # Q2_K: the remaining compute-heavy tensors | |
| "attn_qkv": "Q2_K", | |
| "ffn_up": "Q2_K", | |
| "ffn_gate": "Q2_K", | |
| "ffn_down": "Q2_K", | |
| "ssm_alpha": "Q2_K", | |
| "ssm_beta": "Q2_K", | |
| "nextn.eh_proj": "Q2_K", | |
| } | |
| def _ts() -> str: | |
| return dt.datetime.now().strftime("%H:%M:%S.%f")[:-3] | |
| def _fmt_eta(seconds: float) -> str: | |
| if not np.isfinite(seconds) or seconds <= 0.0: | |
| return "0s" | |
| s = int(round(seconds)) | |
| if s < 60: | |
| return f"{seconds:.1f}s" | |
| m, sec = divmod(s, 60) | |
| if m < 60: | |
| return f"{m}m{sec:02d}s" | |
| h, m = divmod(m, 60) | |
| return f"{h}h{m:02d}m{sec:02d}s" | |
| class HPCQuantizeGUI: | |
| def __init__(self, root: tk.Tk) -> None: | |
| self.root = root | |
| self.root.title("HPC-Quantize V2 — Factored Q1_0 / Q2_K / Q3_K / Q4_0 & Geometry-Preserving Analog Engine") | |
| self.root.geometry("1260x900") | |
| self.root.minsize(1040, 740) | |
| self._log_queue: queue.Queue[tuple[str, object]] = queue.Queue() | |
| self._stop_event = threading.Event() | |
| self._worker: threading.Thread | None = None | |
| self._reader: GGUFReader | None = None | |
| self._imatrix: dict[str, np.ndarray] | None = None | |
| self._start_time: float | None = None | |
| self._last_logged_phase: str = "" | |
| self._init_vars() | |
| self._apply_theme() | |
| self._build_layout() | |
| if self.quant_format_var.get() == "custom": | |
| self._on_format_changed() | |
| self._auto_populate_defaults() | |
| self._update_cli_preview() | |
| self.root.after(80, self._poll_queue) | |
| def _init_vars(self) -> None: | |
| self.gguf_var = tk.StringVar() | |
| self.imatrix_var = tk.StringVar() | |
| self.output_var = tk.StringVar() | |
| self.mode_var = tk.StringVar(value="all") | |
| self.filter_var = tk.StringVar() | |
| self.log_level_var = tk.StringVar(value="ultra") | |
| self.optimizer_var = tk.StringVar(value="hpc") | |
| self.cand_d_var = tk.IntVar(value=6) | |
| self.cand_m_var = tk.IntVar(value=6) | |
| self.starts_var = tk.IntVar(value=2) | |
| self.iters_var = tk.IntVar(value=8) | |
| self.ulp_var = tk.IntVar(value=4) | |
| self.limit_var = tk.IntVar(value=0) | |
| self.workers_var = tk.IntVar(value=0) | |
| self.device_var = tk.StringVar(value="auto") | |
| self.use_analogs_var = tk.BooleanVar(value=True) | |
| self.coupled_q2k_var = tk.BooleanVar(value=True) | |
| self.joint_subscales_var = tk.BooleanVar(value=True) | |
| self.use_spectral_var = tk.BooleanVar(value=True) | |
| self.subblock_sieve_var = tk.BooleanVar(value=True) | |
| self.factor_floor_var = tk.BooleanVar(value=True) | |
| self.cand_floor_var = tk.BooleanVar(value=True) | |
| self.dc_carry_var = tk.BooleanVar(value=True) | |
| self.q4_fallback_var = tk.BooleanVar(value=True) | |
| self.embd_q4_var = tk.BooleanVar(value=True) | |
| self.promote_attn_q4_var = tk.BooleanVar(value=False) | |
| self.quant_format_var = tk.StringVar(value="custom") | |
| self.plan_filter_var = tk.StringVar(value="ALL") | |
| self.custom_type_vars: dict[str, tk.StringVar] = {} | |
| self.dc_lambda_var = tk.DoubleVar(value=1.0) | |
| self.vw_lambda_var = tk.DoubleVar(value=1.0) | |
| self.dc_decay_var = tk.DoubleVar(value=0.85) | |
| self.sse_budget_var = tk.DoubleVar(value=0.0005) | |
| self.thermal_var = tk.IntVar(value=0) | |
| self.thermal_tilt_var = tk.DoubleVar(value=1.0) | |
| self.pin_dc_var = tk.BooleanVar(value=False) | |
| self.cli_preview_var = tk.StringVar() | |
| self.status_var = tk.StringVar(value="Ready.") | |
| self.model_progress_var = tk.DoubleVar(value=0.0) | |
| self.tensor_progress_var = tk.DoubleVar(value=0.0) | |
| # Live telemetry variables | |
| self.tele_tensor_var = tk.StringVar(value="Idle") | |
| self.tele_phase_var = tk.StringVar(value="Waiting to start") | |
| self.tele_blocks_var = tk.StringVar(value="0 / 0") | |
| self.tele_speed_var = tk.StringVar(value="0.0 blk/s (ETA --)") | |
| self.tele_rmse_var = tk.StringVar(value="--") | |
| self.tele_temp_var = tk.StringVar(value="--") | |
| self.tele_floors_var = tk.StringVar(value="cand=0, factor=0") | |
| self.tele_elapsed_var = tk.StringVar(value="0.0s") | |
| for v in ( | |
| self.gguf_var, | |
| self.imatrix_var, | |
| self.output_var, | |
| self.mode_var, | |
| self.optimizer_var, | |
| self.cand_d_var, | |
| self.cand_m_var, | |
| self.limit_var, | |
| self.workers_var, | |
| self.device_var, | |
| self.use_spectral_var, | |
| self.q4_fallback_var, | |
| self.embd_q4_var, | |
| self.promote_attn_q4_var, | |
| self.quant_format_var, | |
| self.thermal_var, | |
| ): | |
| v.trace_add("write", lambda *_: self._update_cli_preview()) | |
| def _apply_theme(self) -> None: | |
| style = ttk.Style(self.root) | |
| if "clam" in style.theme_names(): | |
| style.theme_use("clam") | |
| bg = "#141820" | |
| panel = "#1c222d" | |
| fg = "#e6edf3" | |
| accent = "#3b82f6" | |
| self.root.configure(bg=bg) | |
| style.configure(".", background=bg, foreground=fg, fieldbackground=panel) | |
| style.configure("TFrame", background=bg) | |
| style.configure("TLabelframe", background=bg, foreground=fg) | |
| style.configure("TLabelframe.Label", background=bg, foreground="#93c5fd", font=("Sans", 10, "bold")) | |
| style.configure("TLabel", background=bg, foreground=fg) | |
| style.configure("TeleKey.TLabel", background=bg, foreground="#9ca3af", font=("Sans", 9)) | |
| style.configure("TeleVal.TLabel", background=bg, foreground="#60a5fa", font=("Monospace", 9, "bold")) | |
| style.configure("TCheckbutton", background=bg, foreground=fg) | |
| style.configure("TRadiobutton", background=bg, foreground=fg) | |
| style.configure("TButton", background=panel, foreground=fg, padding=(10, 5)) | |
| style.map("TButton", background=[("active", accent)]) | |
| style.configure("Accent.TButton", background=accent, foreground="#ffffff", font=("Sans", 10, "bold")) | |
| style.configure( | |
| "Treeview", | |
| background=panel, | |
| fieldbackground=panel, | |
| foreground=fg, | |
| rowheight=23, | |
| ) | |
| style.configure("Treeview.Heading", background="#262f3f", foreground=fg, font=("Sans", 9, "bold")) | |
| style.map("Treeview", background=[("selected", accent)]) | |
| def _build_layout(self) -> None: | |
| outer = ttk.Frame(self.root) | |
| outer.pack(fill=tk.BOTH, expand=True) | |
| outer.rowconfigure(0, weight=1) | |
| outer.columnconfigure(0, weight=1) | |
| self._canvas = tk.Canvas(outer, bg="#141820", highlightthickness=0) | |
| v_scroll = ttk.Scrollbar(outer, orient=tk.VERTICAL, command=self._canvas.yview) | |
| h_scroll = ttk.Scrollbar(outer, orient=tk.HORIZONTAL, command=self._canvas.xview) | |
| self._canvas.configure(yscrollcommand=v_scroll.set, xscrollcommand=h_scroll.set) | |
| self._canvas.grid(row=0, column=0, sticky=tk.NSEW) | |
| v_scroll.grid(row=0, column=1, sticky=tk.NS) | |
| h_scroll.grid(row=1, column=0, sticky=tk.EW) | |
| main = ttk.Frame(self._canvas, padding=10) | |
| self._canvas_win = self._canvas.create_window((0, 0), window=main, anchor=tk.NW) | |
| def _on_frame_configure(_event=None) -> None: | |
| self._canvas.configure(scrollregion=self._canvas.bbox("all")) | |
| def _on_canvas_configure(event) -> None: | |
| req_w = max(event.width, main.winfo_reqwidth()) | |
| req_h = max(event.height, main.winfo_reqheight()) | |
| self._canvas.itemconfigure(self._canvas_win, width=req_w, height=req_h) | |
| main.bind("<Configure>", _on_frame_configure) | |
| self._canvas.bind("<Configure>", _on_canvas_configure) | |
| def _on_mousewheel(event) -> None: | |
| w = event.widget | |
| if isinstance(w, (ttk.Treeview, tk.Text)): | |
| return | |
| if getattr(event, "num", None) == 4: | |
| self._canvas.yview_scroll(-1, "units") | |
| elif getattr(event, "num", None) == 5: | |
| self._canvas.yview_scroll(1, "units") | |
| elif getattr(event, "delta", 0): | |
| self._canvas.yview_scroll(int(-1 * (event.delta / 120)), "units") | |
| self.root.bind_all("<MouseWheel>", _on_mousewheel) | |
| self.root.bind_all("<Button-4>", _on_mousewheel) | |
| self.root.bind_all("<Button-5>", _on_mousewheel) | |
| # 1. File Selection Frame | |
| files_frame = ttk.LabelFrame(main, text="1. GGUF & iMatrix Paths", padding=8) | |
| files_frame.pack(fill=tk.X, pady=(0, 6)) | |
| files_frame.columnconfigure(1, weight=1) | |
| ttk.Label(files_frame, text="Source GGUF:").grid(row=0, column=0, sticky=tk.W, padx=(0, 8), pady=2) | |
| ttk.Entry(files_frame, textvariable=self.gguf_var).grid(row=0, column=1, sticky=tk.EW, pady=2) | |
| ttk.Button(files_frame, text="Browse...", command=self._browse_gguf).grid(row=0, column=2, padx=4, pady=2) | |
| ttk.Button(files_frame, text="Inspect GGUF", command=self.inspect_files).grid(row=0, column=3, pady=2) | |
| ttk.Label(files_frame, text="iMatrix (.gguf/.dat):").grid(row=1, column=0, sticky=tk.W, padx=(0, 8), pady=2) | |
| ttk.Entry(files_frame, textvariable=self.imatrix_var).grid(row=1, column=1, sticky=tk.EW, pady=2) | |
| ttk.Button(files_frame, text="Browse...", command=self._browse_imatrix).grid(row=1, column=2, padx=4, pady=2) | |
| ttk.Button(files_frame, text="Clear", command=lambda: self.imatrix_var.set("")).grid(row=1, column=3, pady=2) | |
| ttk.Label(files_frame, text="Output (.gguf/.npz):").grid(row=2, column=0, sticky=tk.W, padx=(0, 8), pady=2) | |
| ttk.Entry(files_frame, textvariable=self.output_var).grid(row=2, column=1, sticky=tk.EW, pady=2) | |
| ttk.Button(files_frame, text="Save As...", command=self._browse_output).grid(row=2, column=2, padx=4, pady=2) | |
| # 2. Middle Split: Left = Settings, Right = Tensor Browser | |
| mid = ttk.PanedWindow(main, orient=tk.HORIZONTAL) | |
| mid.pack(fill=tk.BOTH, expand=True, pady=(0, 6)) | |
| left_pane = ttk.Frame(mid) | |
| right_pane = ttk.Frame(mid) | |
| mid.add(left_pane, weight=2) | |
| mid.add(right_pane, weight=3) | |
| # Left: Engine & Factorization Options | |
| opt_frame = ttk.LabelFrame(left_pane, text="2. Factored Q1_0 / Q2_K / Q3_K / Q4_0 & Analog Controls", padding=8) | |
| opt_frame.pack(fill=tk.BOTH, expand=True, padx=(0, 6)) | |
| mode_row = ttk.Frame(opt_frame) | |
| mode_row.pack(fill=tk.X, pady=(0, 4)) | |
| ttk.Label(mode_row, text="Target Scope:").pack(side=tk.LEFT, padx=(0, 8)) | |
| ttk.Radiobutton( | |
| mode_row, text="All Eligible Tensors", variable=self.mode_var, value="all", | |
| command=self._on_scope_changed, | |
| ).pack(side=tk.LEFT, padx=4) | |
| ttk.Radiobutton( | |
| mode_row, text="Selected Tensor(s)", variable=self.mode_var, value="selected", | |
| command=self._on_scope_changed, | |
| ).pack(side=tk.LEFT, padx=4) | |
| fmt_row = ttk.Frame(opt_frame) | |
| fmt_row.pack(fill=tk.X, pady=(0, 4)) | |
| ttk.Label(fmt_row, text="Quant Format:").pack(side=tk.LEFT, padx=(0, 8)) | |
| for lbl, val in ( | |
| ("Mixed Q2_K + Q4_0", "mixed"), | |
| ("Mixed Q1_0 + Q4_0", "mixed_q1"), | |
| ("Pure Q1_0 (1.125 bpw)", "q1_0"), | |
| ("Pure Q2_K (2.625 bpw)", "q2_k"), | |
| ("Pure Q3_K (3.438 bpw)", "q3_k"), | |
| ("Pure Q4_0 (4.500 bpw)", "q4_0"), | |
| ): | |
| ttk.Radiobutton( | |
| fmt_row, | |
| text=lbl, | |
| variable=self.quant_format_var, | |
| value=val, | |
| command=self._on_format_changed, | |
| ).pack(side=tk.LEFT, padx=3) | |
| custom_row = ttk.Frame(opt_frame) | |
| custom_row.pack(fill=tk.X, pady=(0, 4)) | |
| ttk.Radiobutton( | |
| custom_row, | |
| text="Custom (per tensor type)", | |
| variable=self.quant_format_var, | |
| value="custom", | |
| command=self._on_format_changed, | |
| ).pack(side=tk.LEFT, padx=4) | |
| ttk.Label( | |
| custom_row, | |
| text="Override the quant type per tensor category (Auto = mixed plan).", | |
| ).pack(side=tk.LEFT, padx=6) | |
| self.custom_frame = ttk.LabelFrame(opt_frame, text="Custom Tensor-Type Targets", padding=6) | |
| self.custom_body = ttk.Frame(self.custom_frame) | |
| self.custom_body.pack(fill=tk.X) | |
| self.custom_hint_var = tk.StringVar(value="Load a source GGUF to list tensor types.") | |
| ttk.Label( | |
| self.custom_frame, textvariable=self.custom_hint_var, style="TeleKey.TLabel" | |
| ).pack(anchor=tk.W, pady=(4, 0)) | |
| opt_row = ttk.Frame(opt_frame) | |
| opt_row.pack(fill=tk.X, pady=(0, 4)) | |
| self._custom_anchor = opt_row | |
| ttk.Label(opt_row, text="Global Optimizer:").pack(side=tk.LEFT, padx=(0, 8)) | |
| ttk.Radiobutton( | |
| opt_row, text="HPC (Sieve + 36-State Viterbi)", variable=self.optimizer_var, value="hpc" | |
| ).pack(side=tk.LEFT, padx=4) | |
| ttk.Radiobutton( | |
| opt_row, text="MSE (Local Greedy)", variable=self.optimizer_var, value="mse" | |
| ).pack(side=tk.LEFT, padx=4) | |
| checks = ttk.Frame(opt_frame) | |
| checks.pack(fill=tk.X, pady=2) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Geometry-Preserving Weight Analogs (Iso-Moment + Vesica Gram + Subscale Lattice)", | |
| variable=self.use_analogs_var, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Coupled Orthogonal-Basis Bilinear Q2_K Factorization", | |
| variable=self.coupled_q2k_var, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Exact Joint (Ls, Lm) 16x16 Sub-block Scan", | |
| variable=self.joint_subscales_var, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Spectral Fold / Vesica / DC Objective Penalty", | |
| variable=self.use_spectral_var, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Sub-block 6-State Sieve & Rolling DC Residual Carry", | |
| variable=self.subblock_sieve_var, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Local-Safety Candidate & Factored Floors (Monotone Bound)", | |
| variable=self.factor_floor_var, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Q4_0 Fallback for 32-Aligned Non-Q2_K Tensors & Recurrent Gates (ssm_alpha/beta, ffn_down_exps, hc_*)", | |
| variable=self.q4_fallback_var, | |
| command=self._populate_tensor_tree, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Quantize token_embd.weight & output.weight to Q4_0 (Saves 1.3–3.7 GB)", | |
| variable=self.embd_q4_var, | |
| command=self._populate_tensor_tree, | |
| ).pack(anchor=tk.W, pady=1) | |
| ttk.Checkbutton( | |
| checks, | |
| text="Promote Attention Q/K/V/O Projections to Q4_0 (Mixed Q2_K + Q4_0)", | |
| variable=self.promote_attn_q4_var, | |
| command=self._populate_tensor_tree, | |
| ).pack(anchor=tk.W, pady=1) | |
| grid_f = ttk.Frame(opt_frame) | |
| grid_f.pack(fill=tk.X, pady=4) | |
| for col in range(4): | |
| grid_f.columnconfigure(col, weight=1) | |
| self._spin_pair(grid_f, 0, 0, "Cand d (1-24):", self.cand_d_var, 1, 24) | |
| self._spin_pair(grid_f, 0, 2, "Cand dmin (1-24):", self.cand_m_var, 1, 24) | |
| self._spin_pair(grid_f, 1, 0, "Solver Starts:", self.starts_var, 1, 8) | |
| self._spin_pair(grid_f, 1, 2, "Solver Iters:", self.iters_var, 1, 32) | |
| self._spin_pair(grid_f, 2, 0, "FP16 ULP Radius:", self.ulp_var, 0, 16) | |
| self._spin_pair(grid_f, 2, 2, "Tensor Limit (0=all):", self.limit_var, 0, 9999) | |
| self._spin_pair(grid_f, 3, 0, "Workers (0=Auto CPU):", self.workers_var, 0, 256) | |
| ttk.Label(grid_f, text="Compute Device:").grid(row=3, column=2, sticky=tk.W, padx=4, pady=2) | |
| dev_cb = ttk.Combobox( | |
| grid_f, textvariable=self.device_var, values=("auto", "cuda", "cpu"), state="readonly", width=8 | |
| ) | |
| dev_cb.grid(row=3, column=3, sticky=tk.EW, padx=4, pady=2) | |
| spec_f = ttk.LabelFrame(opt_frame, text="Spectral & DC Parameters", padding=6) | |
| spec_f.pack(fill=tk.X, pady=2) | |
| for col in range(4): | |
| spec_f.columnconfigure(col, weight=1) | |
| ttk.Label(spec_f, text="DC Lambda:").grid(row=0, column=0, sticky=tk.W, padx=4, pady=2) | |
| ttk.Entry(spec_f, textvariable=self.dc_lambda_var, width=8).grid(row=0, column=1, sticky=tk.EW, padx=4, pady=2) | |
| ttk.Label(spec_f, text="Vesica Lambda:").grid(row=0, column=2, sticky=tk.W, padx=4, pady=2) | |
| ttk.Entry(spec_f, textvariable=self.vw_lambda_var, width=8).grid(row=0, column=3, sticky=tk.EW, padx=4, pady=2) | |
| ttk.Label(spec_f, text="DC Decay:").grid(row=1, column=0, sticky=tk.W, padx=4, pady=2) | |
| ttk.Entry(spec_f, textvariable=self.dc_decay_var, width=8).grid(row=1, column=1, sticky=tk.EW, padx=4, pady=2) | |
| ttk.Label(spec_f, text="SSE Budget:").grid(row=1, column=2, sticky=tk.W, padx=4, pady=2) | |
| ttk.Entry(spec_f, textvariable=self.sse_budget_var, width=8).grid(row=1, column=3, sticky=tk.EW, padx=4, pady=2) | |
| ttk.Label(spec_f, text="Thermal Passes (0=off):").grid(row=2, column=0, sticky=tk.W, padx=4, pady=2) | |
| ttk.Spinbox( | |
| spec_f, from_=0, to=16, increment=1, textvariable=self.thermal_var, width=8 | |
| ).grid(row=2, column=1, sticky=tk.EW, padx=4, pady=2) | |
| ttk.Label(spec_f, text="Zero-Residual Tilt (1=off):").grid(row=2, column=2, sticky=tk.W, padx=4, pady=2) | |
| ttk.Entry(spec_f, textvariable=self.thermal_tilt_var, width=8).grid(row=2, column=3, sticky=tk.EW, padx=4, pady=2) | |
| ttk.Checkbutton( | |
| spec_f, | |
| text="Pin DC residual to 0 (Q2_K free lunch)", | |
| variable=self.pin_dc_var, | |
| ).grid(row=3, column=0, columnspan=2, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label( | |
| spec_f, text="(λ multiplier ≥1 during thermal anneal; ~1e2–1e3 ≈ zero-coherent-residual '0-error' anneal)", | |
| foreground="#93c5fd", | |
| ).grid(row=4, column=0, columnspan=4, sticky=tk.W, padx=4, pady=(0, 2)) | |
| # Right: GGUF Tensor Browser | |
| browser_frame = ttk.LabelFrame(right_pane, text="3. GGUF Tensor Inspector & Live Status", padding=8) | |
| browser_frame.pack(fill=tk.BOTH, expand=True) | |
| search_row = ttk.Frame(browser_frame) | |
| search_row.pack(fill=tk.X, pady=(0, 6)) | |
| ttk.Label(search_row, text="Filter:").pack(side=tk.LEFT, padx=(0, 4)) | |
| filter_entry = ttk.Entry(search_row, textvariable=self.filter_var) | |
| filter_entry.pack(side=tk.LEFT, fill=tk.X, expand=True) | |
| filter_entry.bind("<KeyRelease>", lambda _e: self._populate_tensor_tree()) | |
| for label, val in (("All", "ALL"), ("Q1_0", "Q1_0"), ("Q2_K", "Q2_K"), ("Q3_K", "Q3_K"), ("Q4_0", "Q4_0"), ("Copy", "COPY")): | |
| ttk.Radiobutton( | |
| search_row, | |
| text=label, | |
| variable=self.plan_filter_var, | |
| value=val, | |
| command=self._populate_tensor_tree, | |
| ).pack(side=tk.LEFT, padx=3) | |
| ttk.Button( | |
| search_row, text="Select Quantized", command=self._select_all_eligible | |
| ).pack(side=tk.LEFT, padx=4) | |
| cols = ("name", "type", "dims", "row", "q2k", "imat", "state") | |
| self.tree = ttk.Treeview(browser_frame, columns=cols, show="headings", selectmode="extended") | |
| self.tree.heading("name", text="Tensor Name") | |
| self.tree.heading("type", text="Source") | |
| self.tree.heading("dims", text="Dims") | |
| self.tree.heading("row", text="Row Width") | |
| self.tree.heading("q2k", text="Target") | |
| self.tree.heading("imat", text="iMatrix") | |
| self.tree.heading("state", text="Live Status / RMSE") | |
| self.tree.tag_configure("Q1_0", foreground="#fbbf24") | |
| self.tree.tag_configure("Q2_K", foreground="#93c5fd") | |
| self.tree.tag_configure("Q3_K", foreground="#c4b5fd") | |
| self.tree.tag_configure("Q4_0", foreground="#34d399") | |
| self.tree.tag_configure("Copy", foreground="#9ca3af") | |
| self.tree.column("name", width=220, anchor=tk.W) | |
| self.tree.column("type", width=52, anchor=tk.CENTER) | |
| self.tree.column("dims", width=105, anchor=tk.CENTER) | |
| self.tree.column("row", width=70, anchor=tk.E) | |
| self.tree.column("q2k", width=48, anchor=tk.CENTER) | |
| self.tree.column("imat", width=56, anchor=tk.CENTER) | |
| self.tree.column("state", width=165, anchor=tk.W) | |
| self.tree.bind("<<TreeviewSelect>>", self._on_tree_selection) | |
| tree_scroll = ttk.Scrollbar(browser_frame, orient=tk.VERTICAL, command=self.tree.yview) | |
| self.tree.configure(yscrollcommand=tree_scroll.set) | |
| self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) | |
| tree_scroll.pack(side=tk.RIGHT, fill=tk.Y) | |
| # 4. Equivalent CLI Command Preview | |
| cli_frame = ttk.LabelFrame(main, text="4. Equivalent Terminal Command", padding=6) | |
| cli_frame.pack(fill=tk.X, pady=(0, 6)) | |
| ttk.Entry(cli_frame, textvariable=self.cli_preview_var, state="readonly").pack( | |
| side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 6) | |
| ) | |
| ttk.Button(cli_frame, text="Copy Command", command=self._copy_cli).pack(side=tk.RIGHT) | |
| # 5. Live Telemetry Dashboard + Execution + Verbose Console | |
| bottom = ttk.LabelFrame(main, text="5. Live Telemetry Dashboard & Verbose Execution Stream", padding=8) | |
| bottom.pack(fill=tk.BOTH, expand=True) | |
| tele = ttk.Frame(bottom) | |
| tele.pack(fill=tk.X, pady=(0, 6)) | |
| for col in (1, 3, 5, 7): | |
| tele.columnconfigure(col, weight=1) | |
| ttk.Label(tele, text="Active Tensor:", style="TeleKey.TLabel").grid(row=0, column=0, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, textvariable=self.tele_tensor_var, style="TeleVal.TLabel").grid( | |
| row=0, column=1, columnspan=3, sticky=tk.W, padx=4, pady=1 | |
| ) | |
| ttk.Label(tele, text="Current Stage:", style="TeleKey.TLabel").grid(row=0, column=4, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, textvariable=self.tele_phase_var, style="TeleVal.TLabel").grid( | |
| row=0, column=5, columnspan=3, sticky=tk.W, padx=4, pady=1 | |
| ) | |
| ttk.Label(tele, text="Superblocks:", style="TeleKey.TLabel").grid(row=1, column=0, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, textvariable=self.tele_blocks_var, style="TeleVal.TLabel").grid(row=1, column=1, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, text="Throughput:", style="TeleKey.TLabel").grid(row=1, column=2, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, textvariable=self.tele_speed_var, style="TeleVal.TLabel").grid(row=1, column=3, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, text="Running RMSE:", style="TeleKey.TLabel").grid(row=1, column=4, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, textvariable=self.tele_rmse_var, style="TeleVal.TLabel").grid(row=1, column=5, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, text="Sieve Temp / Floors:", style="TeleKey.TLabel").grid(row=1, column=6, sticky=tk.W, padx=4, pady=1) | |
| ttk.Label(tele, textvariable=self.tele_floors_var, style="TeleVal.TLabel").grid(row=1, column=7, sticky=tk.W, padx=4, pady=1) | |
| bars = ttk.Frame(bottom) | |
| bars.pack(fill=tk.X, pady=(0, 6)) | |
| bars.columnconfigure(1, weight=1) | |
| ttk.Label(bars, text="Model Progress:", style="TeleKey.TLabel").grid(row=0, column=0, sticky=tk.W, padx=(0, 6), pady=2) | |
| self.model_progress = ttk.Progressbar(bars, variable=self.model_progress_var, maximum=100.0) | |
| self.model_progress.grid(row=0, column=1, sticky=tk.EW, pady=2) | |
| ttk.Label(bars, text="Tensor Blocks:", style="TeleKey.TLabel").grid(row=1, column=0, sticky=tk.W, padx=(0, 6), pady=2) | |
| self.tensor_progress = ttk.Progressbar(bars, variable=self.tensor_progress_var, maximum=100.0) | |
| self.tensor_progress.grid(row=1, column=1, sticky=tk.EW, pady=2) | |
| btn_row = ttk.Frame(bottom) | |
| btn_row.pack(fill=tk.X, pady=(0, 6)) | |
| self.run_btn = ttk.Button( | |
| btn_row, text="Run Quantization", style="Accent.TButton", command=self.start_quantization | |
| ) | |
| self.run_btn.pack(side=tk.LEFT, padx=(0, 6)) | |
| self.stop_btn = ttk.Button( | |
| btn_row, text="Cancel", state=tk.DISABLED, command=self.stop_worker | |
| ) | |
| self.stop_btn.pack(side=tk.LEFT, padx=(0, 6)) | |
| self.bench_btn = ttk.Button( | |
| btn_row, text="Run Solver Benchmark", command=self.start_benchmark | |
| ) | |
| self.bench_btn.pack(side=tk.LEFT, padx=(0, 6)) | |
| ttk.Button( | |
| btn_row, text="Clear Log", command=lambda: self.log_text.delete("1.0", tk.END) | |
| ).pack(side=tk.LEFT, padx=(0, 12)) | |
| ttk.Label(btn_row, text="Log Verbosity:").pack(side=tk.LEFT, padx=(0, 4)) | |
| ttk.Radiobutton( | |
| btn_row, text="Ultra-Verbose (Every Block Step)", variable=self.log_level_var, value="ultra" | |
| ).pack(side=tk.LEFT, padx=2) | |
| ttk.Radiobutton( | |
| btn_row, text="Stage Transitions", variable=self.log_level_var, value="stages" | |
| ).pack(side=tk.LEFT, padx=2) | |
| ttk.Label(btn_row, textvariable=self.status_var).pack(side=tk.RIGHT, padx=4) | |
| log_frame = ttk.Frame(bottom) | |
| log_frame.pack(fill=tk.BOTH, expand=True) | |
| self.log_text = tk.Text( | |
| log_frame, | |
| height=11, | |
| bg="#0f131a", | |
| fg="#d1d5db", | |
| insertbackground="#ffffff", | |
| font=("Monospace", 9), | |
| wrap=tk.NONE, | |
| ) | |
| log_scroll = ttk.Scrollbar(log_frame, orient=tk.VERTICAL, command=self.log_text.yview) | |
| self.log_text.configure(yscrollcommand=log_scroll.set) | |
| self.log_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) | |
| log_scroll.pack(side=tk.RIGHT, fill=tk.Y) | |
| def _spin_pair(self, parent, row, col, label, var, low, high) -> None: | |
| ttk.Label(parent, text=label).grid(row=row, column=col, sticky=tk.W, padx=4, pady=2) | |
| sp = ttk.Spinbox(parent, from_=low, to=high, textvariable=var, width=6) | |
| sp.grid(row=row, column=col + 1, sticky=tk.EW, padx=4, pady=2) | |
| def _auto_populate_defaults(self) -> None: | |
| if cuda_is_available(): | |
| self._log(f"CUDA GPU detected: {cuda_device_name()} (device=auto will use GPU)") | |
| else: | |
| self._log("CUDA GPU not detected (using multi-core CPU backend)") | |
| default_gguf = Path("Raon.gguf") | |
| default_imat = Path("imatrix.gguf") | |
| if default_imat.exists(): | |
| self.imatrix_var.set(str(default_imat.resolve())) | |
| if default_gguf.exists(): | |
| self.gguf_var.set(str(default_gguf.resolve())) | |
| self.output_var.set(str(default_gguf.with_name("Raon-Q2K.gguf").resolve())) | |
| self.inspect_files() | |
| def _default_out_suffix(self) -> str: | |
| fmt = self.quant_format_var.get() | |
| if fmt == "q1_0": | |
| return "-Q1_0.gguf" | |
| if fmt == "mixed_q1": | |
| return "-Q1_0-Q4_0.gguf" | |
| if fmt == "custom": | |
| return "-Custom.gguf" | |
| if fmt == "q3_k": | |
| return "-Q3_K.gguf" | |
| if fmt == "q4_0": | |
| return "-Q4_0.gguf" | |
| return "-Q2K.gguf" | |
| def _on_format_changed(self) -> None: | |
| cur_out = self.output_var.get().strip() | |
| gguf_p = self.gguf_var.get().strip() | |
| if gguf_p and ( | |
| not cur_out | |
| or any( | |
| cur_out.endswith(sfx) | |
| for sfx in ("-Q2K.gguf", "-Q3_K.gguf", "-Q1_0.gguf", "-Q1_0-Q4_0.gguf", "-Custom.gguf", "-Q4_0.gguf") | |
| ) | |
| ): | |
| p = Path(gguf_p) | |
| self.output_var.set(str(p.with_name(f"{p.stem}{self._default_out_suffix()}"))) | |
| if self.quant_format_var.get() == "custom": | |
| self.custom_frame.pack(fill=tk.X, pady=(0, 4), before=self._custom_anchor) | |
| self._populate_custom_tensor_rows() | |
| else: | |
| self.custom_frame.pack_forget() | |
| self._populate_tensor_tree() | |
| def _custom_quant_map(self) -> dict[str, str]: | |
| return { | |
| key: var.get() | |
| for key, var in self.custom_type_vars.items() | |
| if var.get() not in ("", "Auto") | |
| } | |
| def _custom_map_for_plan(self) -> dict[str, str] | None: | |
| if self.quant_format_var.get() != "custom": | |
| return None | |
| return self._custom_quant_map() or None | |
| def _populate_custom_tensor_rows(self) -> None: | |
| if not hasattr(self, "custom_body"): | |
| return | |
| for child in self.custom_body.winfo_children(): | |
| child.destroy() | |
| if self._reader is None: | |
| self.custom_hint_var.set("Load a source GGUF to list tensor types.") | |
| self.custom_type_vars = {} | |
| return | |
| groups: dict[str, list] = {} | |
| for ti in self._reader.tensors: | |
| groups.setdefault(tensor_type_key(ti.name), []).append(ti) | |
| previous = {key: var.get() for key, var in self.custom_type_vars.items()} | |
| self.custom_type_vars = {} | |
| rows = 0 | |
| for key in sorted(groups): | |
| tensors = groups[key] | |
| options = ["Auto", "Copy"] | |
| if any(is_q1_0_eligible(t.name, t.dims) for t in tensors): | |
| options.append("Q1_0") | |
| if any(is_q2k_eligible(t.name, t.dims) for t in tensors): | |
| options.append("Q2_K") | |
| if any(is_q3_k_eligible(t.name, t.dims) for t in tensors): | |
| options.append("Q3_K") | |
| if any( | |
| is_q4_0_eligible(t.name, t.dims, include_embd=True, allow_q2k_tensors=True) | |
| for t in tensors | |
| ): | |
| options.append("Q4_0") | |
| if len(options) == 2: | |
| continue | |
| var = tk.StringVar( | |
| value=previous.get(key, DEFAULT_CUSTOM_RECIPE.get(key, "Auto")) | |
| ) | |
| if var.get() not in options: | |
| var.set("Auto") | |
| var.trace_add( | |
| "write", | |
| lambda *_a: self._on_custom_type_changed(), | |
| ) | |
| self.custom_type_vars[key] = var | |
| r, c = divmod(rows, 2) | |
| ttk.Label(self.custom_body, text=key, width=18, anchor=tk.W).grid( | |
| row=r, column=c * 2, sticky=tk.W, padx=(0, 4), pady=1 | |
| ) | |
| ttk.Combobox( | |
| self.custom_body, | |
| textvariable=var, | |
| values=options, | |
| state="readonly", | |
| width=8, | |
| ).grid(row=r, column=c * 2 + 1, sticky=tk.W, padx=(0, 12), pady=1) | |
| rows += 1 | |
| self.custom_hint_var.set( | |
| "Quantizable tensor types only; norms/1D tensors and other non-eligible " | |
| "weights are copied unchanged." | |
| ) | |
| self._update_cli_preview() | |
| def _on_custom_type_changed(self) -> None: | |
| self._populate_tensor_tree() | |
| self._update_cli_preview() | |
| def _browse_gguf(self) -> None: | |
| path = filedialog.askopenfilename( | |
| title="Select Source GGUF", | |
| filetypes=[("GGUF Model", "*.gguf"), ("All Files", "*.*")], | |
| ) | |
| if path: | |
| self.gguf_var.set(path) | |
| p = Path(path) | |
| if not self.output_var.get(): | |
| self.output_var.set(str(p.with_name(f"{p.stem}{self._default_out_suffix()}"))) | |
| self.inspect_files() | |
| def _browse_imatrix(self) -> None: | |
| path = filedialog.askopenfilename( | |
| title="Select iMatrix File", | |
| filetypes=[("iMatrix Files", "*.gguf *.dat *.imatrix"), ("All Files", "*.*")], | |
| ) | |
| if path: | |
| self.imatrix_var.set(path) | |
| self.inspect_files() | |
| def _browse_output(self) -> None: | |
| path = filedialog.asksaveasfilename( | |
| title="Select Output File", | |
| defaultextension=".gguf", | |
| filetypes=[("GGUF Model", "*.gguf"), ("NumPy Archive", "*.npz"), ("All Files", "*.*")], | |
| ) | |
| if path: | |
| self.output_var.set(path) | |
| def _log(self, msg: str) -> None: | |
| self.log_text.insert(tk.END, f"[{_ts()}] {msg}\n") | |
| self.log_text.see(tk.END) | |
| def build_config(self) -> HPCConfig: | |
| cfg = HPCConfig( | |
| n_cand_d=int(self.cand_d_var.get()), | |
| n_cand_m=int(self.cand_m_var.get()), | |
| factor_starts=int(self.starts_var.get()), | |
| factor_standalone_iters=int(self.iters_var.get()), | |
| ulp_radius=int(self.ulp_var.get()), | |
| optimizer=self.optimizer_var.get(), | |
| use_weight_analogs=bool(self.use_analogs_var.get()), | |
| factor_coupled_q2k=bool(self.coupled_q2k_var.get()), | |
| factor_joint_subscales=bool(self.joint_subscales_var.get()), | |
| use_spectral=bool(self.use_spectral_var.get()), | |
| subblock_sieve=bool(self.subblock_sieve_var.get()), | |
| use_factor_floor=bool(self.factor_floor_var.get()), | |
| use_candidate_floor=bool(self.cand_floor_var.get()), | |
| apply_dc_carry=bool(self.dc_carry_var.get()), | |
| dc_lambda=float(self.dc_lambda_var.get()), | |
| vw_lambda=float(self.vw_lambda_var.get()), | |
| dc_decay=float(self.dc_decay_var.get()), | |
| sse_budget=float(self.sse_budget_var.get()), | |
| therm_passes=max(0, int(self.thermal_var.get())), | |
| therm_lambda_tilt=max(1.0, float(self.thermal_tilt_var.get())), | |
| pin_dc=bool(self.pin_dc_var.get()), | |
| quant_format=self.quant_format_var.get(), | |
| custom_quant_map=self._custom_map_for_plan() or {}, | |
| enable_q4_fallback=bool(self.q4_fallback_var.get()) and self.quant_format_var.get() not in ("q2_k", "q3_k"), | |
| quantize_embd_q4=bool(self.embd_q4_var.get()), | |
| promote_attn_q4=bool(self.promote_attn_q4_var.get()), | |
| device=self.device_var.get(), | |
| workers=int(self.workers_var.get()), | |
| verbose=False, | |
| ) | |
| return cfg.validate() | |
| def build_cli_command(self) -> str: | |
| cmd = ["python3", "-m", "hpc_quantize_v2"] | |
| gguf = self.gguf_var.get().strip() | |
| if gguf: | |
| cmd += ["--gguf", gguf] | |
| selected = self._selected_tensor_names() | |
| if self.mode_var.get() == "selected" and len(selected) == 1: | |
| cmd += ["--tensor", next(iter(selected))] | |
| else: | |
| cmd.append("--all-q2k") | |
| imat = self.imatrix_var.get().strip() | |
| if imat: | |
| cmd += ["--imatrix-gguf", imat] | |
| out = self.output_var.get().strip() | |
| if out: | |
| cmd += ["--output", out] | |
| if self.limit_var.get() > 0: | |
| cmd += ["--limit", str(self.limit_var.get())] | |
| cmd += ["--format", self.quant_format_var.get()] | |
| if self.quant_format_var.get() == "custom": | |
| custom = self._custom_quant_map() | |
| for key in sorted(custom): | |
| cmd += ["--tensor-type", f"{key}={custom[key]}"] | |
| cmd += ["--device", self.device_var.get()] | |
| cmd += ["--workers", str(self.workers_var.get())] | |
| cmd += ["--cand-d", str(self.cand_d_var.get()), "--cand-m", str(self.cand_m_var.get())] | |
| if self.optimizer_var.get() == "mse": | |
| cmd.append("--mse") | |
| if not self.use_spectral_var.get(): | |
| cmd.append("--no-spectral") | |
| if not self.q4_fallback_var.get(): | |
| cmd.append("--no-q4-fallback") | |
| if not self.embd_q4_var.get(): | |
| cmd.append("--keep-embd") | |
| if self.promote_attn_q4_var.get(): | |
| cmd.append("--promote-attn-q4") | |
| if self.thermal_var.get() > 0: | |
| cmd += ["--thermal", str(int(self.thermal_var.get()))] | |
| if self.thermal_tilt_var.get() > 1.0: | |
| cmd += ["--thermal-tilt", str(float(self.thermal_tilt_var.get()))] | |
| if self.pin_dc_var.get(): | |
| cmd += ["--pin-dc"] | |
| cmd.append("--verbose") | |
| return " ".join(shlex.quote(part) for part in cmd) | |
| def _update_cli_preview(self) -> None: | |
| try: | |
| self.cli_preview_var.set(self.build_cli_command()) | |
| except Exception: | |
| pass | |
| def _copy_cli(self) -> None: | |
| cmd = self.cli_preview_var.get() | |
| self.root.clipboard_clear() | |
| self.root.clipboard_append(cmd) | |
| self.status_var.set("Copied CLI command to clipboard.") | |
| def inspect_files(self) -> None: | |
| imat_path = self.imatrix_var.get().strip() | |
| if imat_path and Path(imat_path).exists(): | |
| try: | |
| self._imatrix = read_imatrix(imat_path) | |
| self._log(f"Loaded iMatrix: {len(self._imatrix)} entries from {imat_path}") | |
| except Exception as exc: | |
| self._imatrix = None | |
| self._log(f"iMatrix load error: {exc}") | |
| else: | |
| self._imatrix = None | |
| gguf_path = self.gguf_var.get().strip() | |
| if not gguf_path or not Path(gguf_path).exists(): | |
| return | |
| try: | |
| self._reader = GGUFReader(gguf_path) | |
| if self.quant_format_var.get() == "custom": | |
| self._populate_custom_tensor_rows() | |
| self._populate_tensor_tree() | |
| except Exception as exc: | |
| self._reader = None | |
| self._log(f"GGUF inspect error: {exc}") | |
| def _plan_target(self, ti, chosen: set[str], scope_selected: bool): | |
| tgt = target_quant_type( | |
| ti.name, | |
| ti.dims, | |
| enable_q4_fallback=bool(self.q4_fallback_var.get()) and self.quant_format_var.get() not in ("q2_k", "q3_k"), | |
| quantize_embd_q4=bool(self.embd_q4_var.get()), | |
| promote_attn_q4=bool(self.promote_attn_q4_var.get()), | |
| quant_format=self.quant_format_var.get(), | |
| source_type=ti.type, | |
| custom_quant_map=self._custom_map_for_plan(), | |
| ) | |
| if scope_selected and ti.name not in chosen: | |
| return None | |
| return tgt | |
| def _on_scope_changed(self) -> None: | |
| self._refresh_plan_view() | |
| self._update_cli_preview() | |
| def _on_tree_selection(self, _event=None) -> None: | |
| if self.mode_var.get() == "selected": | |
| self._refresh_plan_view() | |
| self._update_cli_preview() | |
| def _refresh_plan_view(self) -> None: | |
| if self._reader is None: | |
| return | |
| chosen = self._selected_tensor_names() | |
| scope_selected = self.mode_var.get() == "selected" | |
| n_q2, n_q3, n_q4, n_copy = 0, 0, 0, 0 | |
| n_q1 = 0 | |
| planned_bytes = 0 | |
| for ti in self._reader.tensors: | |
| tgt = self._plan_target(ti, chosen, scope_selected) | |
| if tgt == "Q2_K": | |
| n_q2 += 1 | |
| elif tgt == "Q3_K": | |
| n_q3 += 1 | |
| elif tgt == "Q4_0": | |
| n_q4 += 1 | |
| elif tgt == "Q1_0": | |
| n_q1 += 1 | |
| else: | |
| n_copy += 1 | |
| if tgt == "Q2_K": | |
| planned_bytes += (ti.n_elements // QK_K) * 84 | |
| elif tgt == "Q3_K": | |
| planned_bytes += (ti.n_elements // QK3_K) * Q3_K_BLOCK_BYTES | |
| elif tgt == "Q4_0": | |
| planned_bytes += (ti.n_elements // QK4_0) * 18 | |
| elif tgt == "Q1_0": | |
| planned_bytes += (ti.n_elements // QK1_0) * Q1_0_BLOCK_BYTES | |
| else: | |
| planned_bytes += ti.n_bytes | |
| if not self.tree.exists(ti.name): | |
| continue | |
| tgt_label = tgt if tgt else "Copy" | |
| if scope_selected and ti.name not in chosen: | |
| state_str = "Not selected (copy)" | |
| else: | |
| state_str = ( | |
| f"Pending ({tgt_label})" | |
| if tgt | |
| else (f"Keep {ti.type_name} (<= target)" if ti.type_name in ("Q1_0", "Q2_K", "Q3_K", "Q4_0") else "Passthrough") | |
| ) | |
| vals = list(self.tree.item(ti.name, "values")) | |
| vals[4] = tgt_label | |
| vals[6] = state_str | |
| self.tree.item(ti.name, tags=(tgt_label,), values=vals) | |
| if planned_bytes >= 1024 ** 3: | |
| planned_text = f"{planned_bytes / (1024 ** 3):.2f} GiB" | |
| elif planned_bytes >= 1024 ** 2: | |
| planned_text = f"{planned_bytes / (1024 ** 2):.1f} MiB" | |
| else: | |
| planned_text = f"{planned_bytes / 1024:.1f} KiB" | |
| scope_text = "selected" if scope_selected else "all" | |
| self.status_var.set( | |
| f"Plan ({self.quant_format_var.get().upper()}, {scope_text}): {n_q1} Q1_0 | {n_q2} Q2_K | {n_q3} Q3_K | {n_q4} Q4_0 | {n_copy} Copy " | |
| f"(Total: {len(self._reader.tensors)} tensors, est. {planned_text})" | |
| ) | |
| def _populate_tensor_tree(self) -> None: | |
| chosen = self._selected_tensor_names() | |
| scope_selected = self.mode_var.get() == "selected" | |
| self.tree.delete(*self.tree.get_children()) | |
| if self._reader is None: | |
| return | |
| filt = self.filter_var.get().strip().lower() | |
| plan_filt = self.plan_filter_var.get() | |
| n_q2, n_q3, n_q4, n_copy = 0, 0, 0, 0 | |
| n_q1 = 0 | |
| planned_bytes = 0 | |
| for ti in self._reader.tensors: | |
| tgt = self._plan_target(ti, chosen, scope_selected) | |
| if tgt == "Q2_K": | |
| n_q2 += 1 | |
| elif tgt == "Q3_K": | |
| n_q3 += 1 | |
| elif tgt == "Q4_0": | |
| n_q4 += 1 | |
| elif tgt == "Q1_0": | |
| n_q1 += 1 | |
| else: | |
| n_copy += 1 | |
| if tgt == "Q2_K": | |
| planned_bytes += (ti.n_elements // QK_K) * 84 | |
| elif tgt == "Q3_K": | |
| planned_bytes += (ti.n_elements // QK3_K) * Q3_K_BLOCK_BYTES | |
| elif tgt == "Q4_0": | |
| planned_bytes += (ti.n_elements // QK4_0) * 18 | |
| elif tgt == "Q1_0": | |
| planned_bytes += (ti.n_elements // QK1_0) * Q1_0_BLOCK_BYTES | |
| else: | |
| planned_bytes += ti.n_bytes | |
| tgt_label = tgt if tgt else "Copy" | |
| if plan_filt != "ALL" and tgt_label.upper() != plan_filt: | |
| continue | |
| if ( | |
| filt | |
| and filt not in ti.name.lower() | |
| and filt not in ti.type_name.lower() | |
| and filt not in tgt_label.lower() | |
| ): | |
| continue | |
| has_imat = ( | |
| self._imatrix is not None | |
| and lookup_imatrix(self._imatrix, ti.name) is not None | |
| ) | |
| if scope_selected and ti.name not in chosen: | |
| state_str = "Not selected (copy)" | |
| else: | |
| state_str = ( | |
| f"Pending ({tgt_label})" | |
| if tgt | |
| else (f"Keep {ti.type_name} (<= target)" if ti.type_name in ("Q1_0", "Q2_K", "Q3_K", "Q4_0") else "Passthrough") | |
| ) | |
| self.tree.insert( | |
| "", | |
| tk.END, | |
| iid=ti.name, | |
| tags=(tgt_label,), | |
| values=( | |
| ti.name, | |
| ti.type_name, | |
| str(ti.dims), | |
| ti.row_width, | |
| tgt_label, | |
| "Yes" if has_imat else "-", | |
| state_str, | |
| ), | |
| ) | |
| keep_selected = [n for n in chosen if self.tree.exists(n)] | |
| if keep_selected: | |
| self.tree.selection_set(keep_selected) | |
| if planned_bytes >= 1024 ** 3: | |
| planned_text = f"{planned_bytes / (1024 ** 3):.2f} GiB" | |
| elif planned_bytes >= 1024 ** 2: | |
| planned_text = f"{planned_bytes / (1024 ** 2):.1f} MiB" | |
| else: | |
| planned_text = f"{planned_bytes / 1024:.1f} KiB" | |
| scope_text = "selected" if scope_selected else "all" | |
| self.status_var.set( | |
| f"Plan ({self.quant_format_var.get().upper()}, {scope_text}): {n_q1} Q1_0 | {n_q2} Q2_K | {n_q3} Q3_K | {n_q4} Q4_0 | {n_copy} Copy " | |
| f"(Total: {len(self._reader.tensors)} tensors, est. {planned_text})" | |
| ) | |
| def _select_all_eligible(self) -> None: | |
| if self._reader is None: | |
| return | |
| eligible_ids = [ | |
| ti.name | |
| for ti in self._reader.tensors | |
| if target_quant_type( | |
| ti.name, | |
| ti.dims, | |
| enable_q4_fallback=bool(self.q4_fallback_var.get()) and self.quant_format_var.get() not in ("q2_k", "q3_k"), | |
| quantize_embd_q4=bool(self.embd_q4_var.get()), | |
| promote_attn_q4=bool(self.promote_attn_q4_var.get()), | |
| quant_format=self.quant_format_var.get(), | |
| source_type=ti.type, | |
| custom_quant_map=self._custom_map_for_plan(), | |
| ) | |
| is not None | |
| and self.tree.exists(ti.name) | |
| ] | |
| self.tree.selection_set(eligible_ids) | |
| def _selected_tensor_names(self) -> set[str]: | |
| return set(self.tree.selection()) | |
| def stop_worker(self) -> None: | |
| if self._worker and self._worker.is_alive(): | |
| self._stop_event.set() | |
| self.status_var.set("Stopping immediately...") | |
| self._log("Cancel requested — halting active block loop...") | |
| def start_quantization(self) -> None: | |
| if self._worker and self._worker.is_alive(): | |
| return | |
| gguf_path = self.gguf_var.get().strip() | |
| if not gguf_path or not Path(gguf_path).exists(): | |
| messagebox.showerror("Missing Source GGUF", "Please select a valid source GGUF file.") | |
| return | |
| out_path = self.output_var.get().strip() | |
| if not out_path: | |
| p = Path(gguf_path) | |
| out_path = str(p.with_name(f"{p.stem}-Q2K.gguf")) | |
| self.output_var.set(out_path) | |
| try: | |
| cfg = self.build_config() | |
| except Exception as exc: | |
| messagebox.showerror("Invalid Configuration", str(exc)) | |
| return | |
| selected = self._selected_tensor_names() if self.mode_var.get() == "selected" else None | |
| if self.mode_var.get() == "selected" and not selected: | |
| messagebox.showwarning("No Tensor Selected", "Select one or more tensors in the table first.") | |
| return | |
| imat_path = self.imatrix_var.get().strip() | |
| limit = int(self.limit_var.get()) | |
| self._stop_event.clear() | |
| self._start_time = time.time() | |
| self._last_logged_phase = "" | |
| self.model_progress_var.set(0.0) | |
| self.tensor_progress_var.set(0.0) | |
| self.run_btn.configure(state=tk.DISABLED) | |
| self.bench_btn.configure(state=tk.DISABLED) | |
| self.stop_btn.configure(state=tk.NORMAL) | |
| self.status_var.set("Starting quantization...") | |
| scope_text = "all eligible tensors" if selected is None else f"{len(selected)} selected tensor(s)" | |
| if limit > 0: | |
| scope_text += f", LIMIT={limit} quantized tensor(s) (rest will be copied through!)" | |
| self._log( | |
| f"Starting quantization: source={Path(gguf_path).name} -> output={Path(out_path).name} " | |
| f"(scope={scope_text}, cand={cfg.n_cand_d}x{cfg.n_cand_m}, analogs={cfg.use_weight_analogs}, " | |
| f"coupled={cfg.factor_coupled_q2k}, optimizer={cfg.optimizer.upper()})" | |
| ) | |
| self._worker = threading.Thread( | |
| target=self._quantize_worker, | |
| args=(gguf_path, imat_path, out_path, cfg, selected, limit), | |
| daemon=True, | |
| ) | |
| self._worker.start() | |
| def _quantize_worker( | |
| self, | |
| gguf_path: str, | |
| imat_path: str, | |
| out_path: str, | |
| cfg: HPCConfig, | |
| selected: set[str] | None, | |
| limit: int, | |
| ) -> None: | |
| t0 = time.time() | |
| try: | |
| imat = None | |
| if imat_path and Path(imat_path).exists(): | |
| self._log_queue.put(("log", f"Loading iMatrix from {imat_path} ...")) | |
| imat = read_imatrix(imat_path) | |
| self._log_queue.put(("log", f"Loaded iMatrix: {len(imat)} tensor entries ready.")) | |
| quantizer = Q2KQuantizer(cfg) | |
| if out_path.lower().endswith(".npz") and selected and len(selected) == 1: | |
| reader = GGUFReader(gguf_path) | |
| tname = next(iter(selected)) | |
| ti = reader.info(tname) | |
| x, row = reader.read_tensor(tname) | |
| imp = None | |
| if imat is not None: | |
| raw = lookup_imatrix(imat, tname) | |
| if raw is not None: | |
| imp = expand_importance(raw, x.size, row) | |
| tgt = target_quant_type( | |
| tname, | |
| ti.dims, | |
| enable_q4_fallback=bool(getattr(cfg, "enable_q4_fallback", True)), | |
| quantize_embd_q4=bool(getattr(cfg, "quantize_embd_q4", True)), | |
| promote_attn_q4=bool(getattr(cfg, "promote_attn_q4", False)), | |
| quant_format=str(getattr(cfg, "quant_format", "mixed")), | |
| source_type=ti.type, | |
| custom_quant_map=getattr(cfg, "custom_quant_map", None) or None, | |
| ) | |
| if tgt == "Q1_0": | |
| raw_q1, nb_q1, rmse_q1 = quantize_tensor_q1_0(x, importance=imp, cfg=cfg) | |
| np.savez_compressed( | |
| out_path, | |
| q1_0_bytes=np.frombuffer(raw_q1, dtype=np.uint8), | |
| dequantized=dequantize_q1_0_bytes(raw_q1, nb_q1), | |
| rmse=np.float32(rmse_q1), | |
| ) | |
| self._log_queue.put( | |
| ("done", f"Saved Q1_0 {out_path} (RMSE={rmse_q1:.6e}, {time.time() - t0:.1f}s)") | |
| ) | |
| return | |
| if tgt == "Q3_K": | |
| raw_q3, nb_q3, rmse_q3 = quantize_tensor_q3_k(x, importance=imp, cfg=cfg) | |
| np.savez_compressed( | |
| out_path, | |
| q3_k_bytes=np.frombuffer(raw_q3, dtype=np.uint8), | |
| dequantized=dequantize_q3_k_bytes(raw_q3, nb_q3), | |
| rmse=np.float32(rmse_q3), | |
| ) | |
| self._log_queue.put( | |
| ("done", f"Saved Q3_K {out_path} (RMSE={rmse_q3:.6e}, {time.time() - t0:.1f}s)") | |
| ) | |
| return | |
| if tgt == "Q4_0": | |
| raw_q4, nb_q4, rmse_q4 = quantize_tensor_q4_0(x, importance=imp, cfg=cfg) | |
| np.savez_compressed( | |
| out_path, | |
| q4_0_bytes=np.frombuffer(raw_q4, dtype=np.uint8), | |
| dequantized=dequantize_q4_0_bytes(raw_q4, nb_q4), | |
| rmse=np.float32(rmse_q4), | |
| ) | |
| self._log_queue.put( | |
| ("done", f"Saved Q4_0 {out_path} (RMSE={rmse_q4:.6e}, {time.time() - t0:.1f}s)") | |
| ) | |
| return | |
| if tgt != "Q2_K": | |
| raise ValueError(f"{tname}: target {tgt!r} is not quantizable to .npz") | |
| res = quantizer.quantize( | |
| x, | |
| importance=imp, | |
| row_width=row, | |
| status_callback=lambda ev: self._log_queue.put(("stage", (1, 1, ti, ev))), | |
| stop_event=self._stop_event, | |
| ) | |
| np.savez_compressed( | |
| out_path, | |
| scales=res.scales, | |
| qs=res.qs, | |
| dm=res.dm, | |
| dequantized=res.dequantize(), | |
| rmse=np.float32(res.stats.rmse), | |
| ) | |
| self._log_queue.put( | |
| ("done", f"Saved {out_path} (RMSE={res.stats.rmse:.6e}, {time.time() - t0:.1f}s)") | |
| ) | |
| return | |
| def on_stage(idx: int, total: int, ti, ev: dict): | |
| self._log_queue.put(("stage", (idx, total, ti, ev))) | |
| def on_progress(done: int, total: int, name: str, action: str, rmse: float | None, has_imat: bool): | |
| self._log_queue.put(("tensor_done", (done, total, name, action, rmse, has_imat))) | |
| stats = write_quantized_gguf( | |
| gguf_path, | |
| out_path, | |
| quantizer, | |
| imat=imat, | |
| quantize_all=(selected is None), | |
| tensor_names=selected, | |
| limit=limit, | |
| verbose=False, | |
| progress_callback=on_progress, | |
| stage_callback=on_stage, | |
| stop_event=self._stop_event, | |
| ) | |
| dt_sec = time.time() - t0 | |
| self._log_queue.put( | |
| ( | |
| "done", | |
| f"Wrote {out_path}: {int(stats.get('q1_0', 0))} Q1_0 + {int(stats.get('q2_k', 0))} Q2_K + " | |
| f"{int(stats.get('q3_k', 0))} Q3_K + {int(stats.get('q4_0', 0))} Q4_0 " | |
| f"({int(stats['quantized'])}/{int(stats['tensors'])} tensors), " | |
| f"overall RMSE={stats['rmse']:.6e} ({dt_sec:.1f}s)", | |
| ) | |
| ) | |
| except InterruptedError as exc: | |
| self._log_queue.put(("cancelled", str(exc))) | |
| except Exception as exc: | |
| self._log_queue.put(("error", str(exc))) | |
| def start_benchmark(self) -> None: | |
| if self._worker and self._worker.is_alive(): | |
| return | |
| try: | |
| cfg = self.build_config() | |
| except Exception as exc: | |
| messagebox.showerror("Invalid Configuration", str(exc)) | |
| return | |
| self._stop_event.clear() | |
| self._start_time = time.time() | |
| self.model_progress_var.set(0.0) | |
| self.tensor_progress_var.set(0.0) | |
| self.run_btn.configure(state=tk.DISABLED) | |
| self.bench_btn.configure(state=tk.DISABLED) | |
| self.stop_btn.configure(state=tk.NORMAL) | |
| self.status_var.set("Running factored solver benchmark...") | |
| self._worker = threading.Thread(target=self._bench_worker, args=(cfg,), daemon=True) | |
| self._worker.start() | |
| def _bench_worker(self, cfg: HPCConfig) -> None: | |
| from collections import defaultdict | |
| try: | |
| cases = synthetic_cases(123, 8) | |
| gains = defaultdict(list) | |
| total = len(cases) | |
| for idx, (kind, x) in enumerate(cases, 1): | |
| if self._stop_event.is_set(): | |
| raise InterruptedError("Benchmark cancelled.") | |
| w = np.ones(x.size, dtype=np.float32) | |
| v2 = factor_only_solve(x, w, cfg) | |
| ref_obj, _ = reference_solve(x, w, cfg, cfg.use_spectral) | |
| gain_pct = (ref_obj - v2.objective) / max(abs(ref_obj), 1.0e-30) * 100.0 | |
| gains[kind].append(gain_pct / 100.0) | |
| self._log_queue.put( | |
| ( | |
| "bench_step", | |
| ( | |
| idx, | |
| total, | |
| kind, | |
| f"Case {idx}/{total} [{kind}]: ref={ref_obj:.5e} -> V2={v2.objective:.5e} " | |
| f"(+{gain_pct:.2f}%, d={float(v2.d):.5f}, dmin={float(v2.dmin):.5f}, starts={v2.starts})", | |
| ), | |
| ) | |
| ) | |
| self._log_queue.put( | |
| ("log", f"=== Summary (spectral={cfg.use_spectral}, analogs={cfg.use_weight_analogs}) ===") | |
| ) | |
| for kind, vals in gains.items(): | |
| arr = np.asarray(vals) | |
| self._log_queue.put( | |
| ( | |
| "log", | |
| f" {kind:14s} mean={arr.mean()*100:6.2f}% median={np.median(arr)*100:6.2f}% " | |
| f"min={arr.min()*100:6.2f}% worse={int(np.sum(arr < -1e-9))}/{arr.size}", | |
| ) | |
| ) | |
| self._log_queue.put(("done", "Benchmark complete.")) | |
| except InterruptedError as exc: | |
| self._log_queue.put(("cancelled", str(exc))) | |
| except Exception as exc: | |
| self._log_queue.put(("error", str(exc))) | |
| def _update_tree_row_state(self, name: str, state_text: str, focus: bool = False) -> None: | |
| if not self.tree.exists(name): | |
| return | |
| vals = list(self.tree.item(name, "values")) | |
| if len(vals) >= 7: | |
| vals[6] = state_text | |
| self.tree.item(name, values=vals) | |
| if focus: | |
| self.tree.see(name) | |
| def _poll_queue(self) -> None: | |
| while True: | |
| try: | |
| kind, payload = self._log_queue.get_nowait() | |
| except queue.Empty: | |
| break | |
| if kind == "log": | |
| self._log(str(payload)) | |
| elif kind == "stage": | |
| idx, total, ti, ev = payload # type: ignore[misc] | |
| phase = ev.get("phase", "") | |
| done = int(ev.get("done", 0)) | |
| tot_blk = max(int(ev.get("total", 1)), 1) | |
| detail = ev.get("detail", "") | |
| blk_pct = 100.0 * done / tot_blk | |
| overall_pct = float( | |
| ev.get("model_pct", 100.0 * ((idx - 1) + (done / tot_blk)) / max(total, 1)) | |
| ) | |
| self.model_progress_var.set(overall_pct) | |
| self.tensor_progress_var.set(blk_pct) | |
| self.tele_tensor_var.set(f"[{idx}/{total}] {ti.name} ({ti.type_name}, dims={ti.dims})") | |
| self.tele_phase_var.set(phase) | |
| if "model_total_blocks" in ev and ev["model_total_blocks"] > 0: | |
| self.tele_blocks_var.set( | |
| f"Tensor: {done:,}/{tot_blk:,} ({blk_pct:.1f}%) | " | |
| f"Model: {ev['model_done_blocks']:,}/{ev['model_total_blocks']:,} ({overall_pct:.1f}%)" | |
| ) | |
| else: | |
| self.tele_blocks_var.set(f"{done:,} / {tot_blk:,} ({blk_pct:.1f}%)") | |
| if "rate" in ev and "eta" in ev: | |
| t_eta = _fmt_eta(float(ev["eta"])) | |
| m_eta = _fmt_eta(float(ev.get("model_eta", ev["eta"]))) | |
| self.tele_speed_var.set( | |
| f"{ev['rate']:.1f} blk/s | Tensor ETA: {t_eta} | Model ETA: {m_eta}" | |
| ) | |
| if "rmse" in ev and "sigma" in ev: | |
| r, s = float(ev["rmse"]), float(ev["sigma"]) | |
| self.tele_rmse_var.set(f"{r:.6e} (r/σ={r/max(s, 1e-15):.4f})") | |
| if "temperature" in ev or "cand_floors" in ev: | |
| t_val = ev.get("temperature", 0.0) | |
| cf = ev.get("cand_floors", 0) | |
| ff = ev.get("fac_floors", 0) | |
| self.tele_floors_var.set(f"T={t_val:.2e} | cand={cf}, fac={ff}") | |
| self.status_var.set(f"[{idx}/{total}] {ti.name} — {phase} ({blk_pct:.0f}%)") | |
| self._update_tree_row_state(ti.name, f"{phase.split(':')[0]} ({blk_pct:.0f}%)", focus=True) | |
| is_Copy = phase.startswith("Passthrough Copy") | |
| phase_key = f"{ti.name}::{phase}" | |
| if not is_Copy: | |
| if self.log_level_var.get() == "ultra" or phase_key != self._last_logged_phase: | |
| self._log(f"[{idx}/{total}] {ti.name} | {phase} | {detail}") | |
| self._last_logged_phase = phase_key | |
| elif kind == "tensor_done": | |
| done, total, name, action, rmse, has_imat = payload # type: ignore[misc] | |
| self.model_progress_var.set(100.0 * done / max(total, 1)) | |
| self.tensor_progress_var.set(100.0) | |
| if action in ("Q1_0", "Q2_K", "Q3_K", "Q4_0") and rmse is not None: | |
| self._update_tree_row_state(name, f"{action} (RMSE={rmse:.4e})") | |
| self._log( | |
| f"[{done}/{total}] FINISHED {name:42s} -> {action} RMSE={rmse:.6e} (iMatrix={'yes' if has_imat else 'no'})" | |
| ) | |
| else: | |
| self._update_tree_row_state(name, "Copied verbatim") | |
| if self.log_level_var.get() == "ultra" or done % 25 == 0 or done == total: | |
| self._log(f"[{done}/{total}] COPIED {name}") | |
| elif kind == "bench_step": | |
| idx, total, bkind, msg = payload # type: ignore[misc] | |
| pct = 100.0 * idx / max(total, 1) | |
| self.model_progress_var.set(pct) | |
| self.tensor_progress_var.set(pct) | |
| self.tele_tensor_var.set(f"Synthetic Benchmark ({bkind})") | |
| self.tele_phase_var.set(f"Block {idx}/{total}") | |
| self.tele_blocks_var.set(f"{idx} / {total}") | |
| self._log(str(msg)) | |
| elif kind == "done": | |
| self.model_progress_var.set(100.0) | |
| self.tensor_progress_var.set(100.0) | |
| self.tele_phase_var.set("Complete") | |
| self.status_var.set(str(payload)) | |
| self._log(str(payload)) | |
| self._reset_buttons() | |
| elif kind in ("cancelled", "error"): | |
| self.tele_phase_var.set(kind.upper()) | |
| self.status_var.set(f"{kind.upper()}: {payload}") | |
| self._log(f"{kind.upper()}: {payload}") | |
| self._reset_buttons() | |
| self.root.after(80, self._poll_queue) | |
| def _reset_buttons(self) -> None: | |
| self.run_btn.configure(state=tk.NORMAL) | |
| self.bench_btn.configure(state=tk.NORMAL) | |
| self.stop_btn.configure(state=tk.DISABLED) | |
| def main() -> None: | |
| parser = argparse.ArgumentParser(description="HPC-Quantize V2 GUI") | |
| parser.add_argument("--gguf", help="pre-populate source GGUF path") | |
| parser.add_argument("--imatrix", help="pre-populate iMatrix path") | |
| parser.add_argument("--output", help="pre-populate output GGUF path") | |
| parser.add_argument("--check", action="store_true", help="validate GUI bindings without opening a window") | |
| args = parser.parse_args() | |
| if args.check: | |
| cfg = HPCConfig().validate() | |
| print("GUI check OK:", cfg) | |
| return | |
| root = tk.Tk() | |
| app = HPCQuantizeGUI(root) | |
| if args.gguf: | |
| app.gguf_var.set(args.gguf) | |
| if args.imatrix: | |
| app.imatrix_var.set(args.imatrix) | |
| if args.output: | |
| app.output_var.set(args.output) | |
| if args.gguf or args.imatrix: | |
| app.inspect_files() | |
| root.mainloop() | |
| if __name__ == "__main__": | |
| main() | |