mirror of
https://github.com/MartinGia/lora-analyzer.git
synced 2026-03-28 17:43:01 +01:00
170 lines
4.6 KiB
Python
170 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
LoRA Analyzer CLI
|
|
Herramienta de línea de comandos para analizar archivos LoRA
|
|
"""
|
|
|
|
import argparse
|
|
import sys
|
|
import json
|
|
from pathlib import Path
|
|
from lora_analyzer import LoRAAnalyzer, format_analysis_report
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Analiza archivos LoRA y extrae información técnica",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog="""
|
|
Ejemplos de uso:
|
|
# Analizar un archivo
|
|
python lora_cli.py mi_lora.safetensors
|
|
|
|
# Guardar resultado en JSON
|
|
python lora_cli.py mi_lora.safetensors --output resultado.json
|
|
|
|
# Analizar múltiples archivos
|
|
python lora_cli.py lora1.safetensors lora2.pt lora3.ckpt
|
|
|
|
# Modo verbose con más detalles
|
|
python lora_cli.py mi_lora.safetensors --verbose
|
|
"""
|
|
)
|
|
|
|
parser.add_argument(
|
|
"files",
|
|
nargs="+",
|
|
help="Archivo(s) LoRA a analizar (.safetensors, .pt, .ckpt)"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-o", "--output",
|
|
help="Guardar resultado en archivo JSON",
|
|
type=str
|
|
)
|
|
|
|
parser.add_argument(
|
|
"-v", "--verbose",
|
|
action="store_true",
|
|
help="Mostrar información detallada"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--json",
|
|
action="store_true",
|
|
help="Salida en formato JSON"
|
|
)
|
|
|
|
parser.add_argument(
|
|
"--compare",
|
|
action="store_true",
|
|
help="Comparar múltiples LoRAs (requiere 2+ archivos)"
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Validar archivos
|
|
files = [Path(f) for f in args.files]
|
|
for f in files:
|
|
if not f.exists():
|
|
print(f"❌ Error: El archivo no existe: {f}", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
results = []
|
|
|
|
# Analizar cada archivo
|
|
for file_path in files:
|
|
print(f"\n🔍 Analizando: {file_path.name}")
|
|
print("-" * 70)
|
|
|
|
try:
|
|
analyzer = LoRAAnalyzer(str(file_path))
|
|
analysis = analyzer.analyze()
|
|
results.append(analysis)
|
|
|
|
if args.json:
|
|
print(json.dumps(analysis, indent=2, ensure_ascii=False))
|
|
else:
|
|
print(format_analysis_report(analysis))
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error al analizar {file_path.name}: {str(e)}", file=sys.stderr)
|
|
if args.verbose:
|
|
import traceback
|
|
traceback.print_exc()
|
|
|
|
# Modo comparación
|
|
if args.compare and len(results) > 1:
|
|
print("\n" + "=" * 70)
|
|
print("📊 COMPARACIÓN DE LORAS")
|
|
print("=" * 70)
|
|
compare_loras(results)
|
|
|
|
# Guardar en JSON si se especificó
|
|
if args.output and results:
|
|
output_path = Path(args.output)
|
|
with open(output_path, 'w', encoding='utf-8') as f:
|
|
json.dump(results, f, indent=2, ensure_ascii=False)
|
|
print(f"\n✅ Resultados guardados en: {output_path}")
|
|
|
|
|
|
def compare_loras(results):
|
|
"""Compara múltiples LoRAs"""
|
|
print("\n📋 Comparación de características:\n")
|
|
|
|
# Tabla comparativa
|
|
headers = ["Característica"] + [r["file_info"]["nombre"] for r in results]
|
|
|
|
comparisons = []
|
|
|
|
# Tamaño
|
|
row = ["Tamaño (MB)"]
|
|
for r in results:
|
|
row.append(f"{r['file_info'].get('tamaño_mb', 'N/A')}")
|
|
comparisons.append(row)
|
|
|
|
# Rank
|
|
row = ["Rank"]
|
|
for r in results:
|
|
rank_info = r.get("architecture", {}).get("rank_info", {})
|
|
rank = rank_info.get("most_common_rank", "N/A")
|
|
row.append(str(rank))
|
|
comparisons.append(row)
|
|
|
|
# Capas
|
|
row = ["Total capas"]
|
|
for r in results:
|
|
layers = r.get("architecture", {}).get("total_layers", "N/A")
|
|
row.append(str(layers))
|
|
comparisons.append(row)
|
|
|
|
# Imágenes de entrenamiento
|
|
row = ["Imágenes entreno"]
|
|
for r in results:
|
|
num_images = r.get("metadata", {}).get("ss_num_train_images", "N/A")
|
|
row.append(str(num_images))
|
|
comparisons.append(row)
|
|
|
|
# Learning rate
|
|
row = ["Learning rate"]
|
|
for r in results:
|
|
lr = r.get("metadata", {}).get("ss_learning_rate", "N/A")
|
|
row.append(str(lr))
|
|
comparisons.append(row)
|
|
|
|
# Imprimir tabla
|
|
col_widths = [max(len(str(row[i])) for row in [headers] + comparisons) + 2
|
|
for i in range(len(headers))]
|
|
|
|
# Header
|
|
print(" ".join(h.ljust(w) for h, w in zip(headers, col_widths)))
|
|
print("-" * sum(col_widths))
|
|
|
|
# Filas
|
|
for row in comparisons:
|
|
print(" ".join(str(cell).ljust(w) for cell, w in zip(row, col_widths)))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|