| from __future__ import annotations |
|
|
| from pathlib import Path |
|
|
| import gradio as gr |
|
|
| from models.model_catalog import ModelInfo |
| from training.export import ( |
| QUANTIZATION_CHOICES, |
| build_export_plan, |
| list_exported_files, |
| ) |
| from ui.progress import CLICK_PROGRESS |
|
|
|
|
| def export_download_paths(plan: dict | None, exported_rows: list[list[str]]) -> list[str]: |
| """Return existing exported files for the Gradio download output.""" |
| existing_paths = [ |
| Path(row[0]) |
| for row in exported_rows |
| if row and Path(row[0]).is_file() |
| ] |
| if not plan: |
| return [str(path) for path in existing_paths] |
|
|
| planned_paths = _planned_export_paths(plan) |
| planned_keys = {_path_key(path) for path in planned_paths} |
| planned_existing = [ |
| path for path in existing_paths if _path_key(path) in planned_keys |
| ] |
| other_existing = [ |
| path for path in existing_paths if _path_key(path) not in planned_keys |
| ] |
| return [str(path) for path in [*planned_existing, *other_existing]] |
|
|
|
|
| def _planned_export_paths(plan: dict) -> list[Path]: |
| output_dir = Path(str(plan.get("output_dir") or "")) |
| paths: list[Path] = [] |
|
|
| official_file = str(plan.get("official_gguf_file") or "") |
| if official_file: |
| paths.append(output_dir / official_file) |
|
|
| convert_command = plan.get("convert_command") or [] |
| if "--outfile" in convert_command: |
| outfile_index = convert_command.index("--outfile") + 1 |
| if outfile_index < len(convert_command): |
| paths.append(Path(str(convert_command[outfile_index]))) |
|
|
| quantize_command = plan.get("quantize_command") or [] |
| if len(quantize_command) >= 3: |
| paths.append(Path(str(quantize_command[2]))) |
|
|
| return paths |
|
|
|
|
| def _path_key(path: Path) -> str: |
| return str(path.resolve()) |
|
|
|
|
| def build_export_tab(catalog: dict[str, ModelInfo]) -> None: |
| model_id = gr.Dropdown(list(catalog), value=next(iter(catalog)), label="Model") |
| quant = gr.Dropdown(QUANTIZATION_CHOICES, value="Q4_K_M", label="Quantization") |
| output_dir = gr.Textbox(label="Output directory", value="exports") |
| run = gr.Button("Prepare export plan", variant="primary") |
| refresh = gr.Button("Refresh exported files") |
| output = gr.JSON(label="Export plan") |
| files = gr.Dataframe(headers=["path", "bytes"], label="Exported files", interactive=False) |
| downloads = gr.File( |
| label="Download exported files", |
| file_count="multiple", |
| interactive=False, |
| ) |
|
|
| def plan_export( |
| selected: str, |
| selected_quant: str, |
| directory: str, |
| ) -> tuple[dict, list[list[str]], list[str]]: |
| model = catalog[selected] |
| plan = build_export_plan(model, selected_quant, directory) |
| exported_rows = list_exported_files(directory) |
| plan_data = plan.as_dict() |
| return plan_data, exported_rows, export_download_paths(plan_data, exported_rows) |
|
|
| def refresh_exports(directory: str) -> tuple[list[list[str]], list[str]]: |
| exported_rows = list_exported_files(directory) |
| return exported_rows, export_download_paths(None, exported_rows) |
|
|
| run.click( |
| plan_export, |
| [model_id, quant, output_dir], |
| [output, files, downloads], |
| show_progress=CLICK_PROGRESS, |
| ) |
| refresh.click( |
| refresh_exports, |
| output_dir, |
| [files, downloads], |
| show_progress=CLICK_PROGRESS, |
| ) |
|
|