Files
lora-analyzer/lora_cli.py

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()