llm-gguf-tools/helpers/quantisation/progress.py
2025-08-09 17:16:02 +01:00

151 lines
5.8 KiB
Python

"""Progress tracking and reporting for quantisation workflow.
Provides utilities for tracking quantisation progress, generating
status reports, and displaying completion summaries.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from helpers.logger import logger
if TYPE_CHECKING:
from helpers.models.quantisation import ModelSource, QuantisationResult, QuantisationType
class ProgressReporter:
"""Reports progress and status of quantisation operations.
Provides methods for displaying model information, progress updates,
and completion summaries throughout the quantisation workflow.
"""
@staticmethod
def print_model_info(model_source: ModelSource, username: str, work_dir: str) -> None:
"""Print model information at start of processing.
Displays comprehensive information about the model being processed,
including source details, author information, and working directory
to provide clear context at the beginning of quantisation workflows.
"""
logger.info(f"Source URL: {model_source.url}")
logger.info(f"Source model: {model_source.source_model}")
logger.info(f"Original author: {model_source.original_author}")
logger.info(f"Model name: {model_source.model_name}")
logger.info(f"Your HF username: {username}")
logger.info(f"Working directory: {work_dir}")
@staticmethod
def print_quantisation_start(
index: int,
total: int,
quant_type: str,
) -> None:
"""Print message when starting a quantisation.
Displays progress information showing which quantisation is currently
being processed within the overall batch, providing clear feedback
about workflow advancement and the specific type being quantised.
"""
logger.info(f"Processing quantisation {index}/{total}: {quant_type}")
@staticmethod
def print_completion_summary(
model_source: ModelSource,
results: dict[QuantisationType, QuantisationResult],
output_repo: str,
) -> None:
"""Print completion summary with results.
Generates comprehensive completion report showing successful quantisations,
file information, and repository links. Provides detailed feedback on
the overall quantisation workflow outcome and model availability.
"""
successful_results = [r for r in results.values() if r.success]
if successful_results:
logger.info("Complete! Your quantised models are available at:")
logger.info(f" https://huggingface.co/{output_repo}")
logger.info("Model info:")
logger.info(f" - Source URL: {model_source.url}")
logger.info(f" - Original: {model_source.source_model}")
logger.info(
" - Method: "
f"{'Direct GGUF download' if model_source.is_gguf_repo else 'HF model conversion'}"
)
logger.info(f" - Quantised: {output_repo}")
for result in successful_results:
if result.file_size:
filename = (
f"{model_source.original_author}-{model_source.model_name}-"
f"{result.quantisation_type}.gguf"
)
logger.info(f" - {result.quantisation_type}: {filename} ({result.file_size})")
else:
logger.error(
"All quantisations failed - repository created with documentation "
"but no model files"
)
logger.error(f" Repository: https://huggingface.co/{output_repo}")
@staticmethod
def print_upload_summary(completed: int, failed: int) -> None:
"""Print upload completion summary.
Reports the final upload statistics showing successful and failed
uploads with appropriate warning or success messaging based on
the outcome of the upload batch process.
"""
if failed > 0:
logger.warning(f"Upload summary: {completed} succeeded, {failed} failed")
else:
logger.info(f"All {completed} uploads completed successfully")
@staticmethod
def print_architecture_warning() -> None:
"""Print warning about unsupported architecture."""
logger.warning("⚠️ Architecture not supported by llama.cpp - K-quants will be skipped")
logger.info("💡 Basic types (Q4_0, Q5_0, Q6_0, Q8_0) will still be generated")
@staticmethod
def get_status_emoji(status: str) -> str:
"""Get emoji for a given status.
Maps status strings to appropriate emoji representations for enhanced
visual feedback in progress reporting. Provides a default emoji for
unknown status values to maintain consistent display formatting.
Returns:
Appropriate emoji for the status.
"""
status_emojis = {
"planned": "📋",
"processing": "⚙️",
"uploading": "📤",
"completed": "",
"failed": "",
}
return status_emojis.get(status, "")
@staticmethod
def format_progress_bar(current: int, total: int, width: int = 30) -> str:
"""Format a text progress bar.
Creates a visual progress representation using Unicode block characters
with percentage display. Handles edge cases like zero totals and
calculates appropriate fill ratios for the specified width.
Returns:
Formatted progress bar string.
"""
if total == 0:
return "[" + " " * width + "]"
progress = int((current / total) * width)
filled = "" * progress
empty = "" * (width - progress)
percentage = (current / total) * 100
return f"[{filled}{empty}] {percentage:.1f}%"