Created
September 11, 2025 23:39
-
-
Save wzorroman/55c65c1a009808d90d5fa61c6296d1e6 to your computer and use it in GitHub Desktop.
Script de comparacion de modelos Ollama
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # model_comparison.py | |
| # reference: https://ollama.com/library/gpt-oss | |
| import ollama | |
| import time | |
| import json | |
| from datetime import datetime | |
| from typing import Dict, List, Any | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| from functools import wraps | |
| def medir_tiempo(func): | |
| """Decorador para medir tiempo de ejecución""" | |
| @wraps(func) | |
| def wrapper(*args, **kwargs): | |
| inicio = time.time() | |
| resultado = func(*args, **kwargs) | |
| fin = time.time() | |
| print(f"⏱️ {func.__name__}: {fin - inicio:.3f}s") | |
| return resultado, fin - inicio | |
| return wrapper | |
| class ModelComparator: | |
| def __init__(self): | |
| self.results = [] | |
| self.metrics = {} | |
| @medir_tiempo | |
| def ejecutar_modelo(self, model_name: str, prompt: str) -> str: | |
| """Ejecutar un modelo con un prompt específico""" | |
| try: | |
| response = ollama.chat( | |
| model=model_name, | |
| messages=[{'role': 'user', 'content': prompt}] | |
| ) | |
| return response['message']['content'] | |
| except Exception as e: | |
| return f"ERROR: {str(e)}" | |
| def comparar_modelos(self, modelos: List[str], prompts: List[str], iteraciones: int = 3): | |
| """Comparar múltiples modelos con varios prompts""" | |
| print(f"🚀 Iniciando comparativa de {len(modelos)} modelos...") | |
| print(f"📝 {len(prompts)} prompts, {iteraciones} iteraciones cada uno\n") | |
| resultados_completos = [] | |
| for i, prompt in enumerate(prompts, 1): | |
| print(f"📋 Prompt {i}: '{prompt[:50]}...'") | |
| for modelo in modelos: | |
| print(f" 🔍 Probando {modelo}...") | |
| tiempos = [] | |
| respuestas = [] | |
| for iter in range(iteraciones): | |
| respuesta, tiempo = self.ejecutar_modelo(modelo, prompt) | |
| tiempos.append(tiempo) | |
| respuestas.append(respuesta) | |
| print(f" Iteración {iter + 1}: {tiempo:.2f}s") | |
| # Calcular métricas | |
| avg_time = sum(tiempos) / len(tiempos) | |
| min_time = min(tiempos) | |
| max_time = max(tiempos) | |
| resultado = { | |
| 'modelo': modelo, | |
| 'prompt': prompt, | |
| 'iteraciones': iteraciones, | |
| 'tiempo_promedio': avg_time, | |
| 'tiempo_minimo': min_time, | |
| 'tiempo_maximo': max_time, | |
| 'tiempos': tiempos, | |
| 'respuesta_ejemplo': respuestas[0][:200] + "..." if len(respuestas[0]) > 200 else respuestas[0] | |
| } | |
| resultados_completos.append(resultado) | |
| print(f" ✅ {modelo}: {avg_time:.2f}s promedio\n") | |
| self.results = resultados_completos | |
| return resultados_completos | |
| def generar_estadisticas(self): | |
| """Generar estadísticas comparativas""" | |
| if not self.results: | |
| return {} | |
| estadisticas = {} | |
| for resultado in self.results: | |
| modelo = resultado['modelo'] | |
| if modelo not in estadisticas: | |
| estadisticas[modelo] = { | |
| 'total_prompts': 0, | |
| 'tiempos_totales': [], | |
| 'avg_general': 0, | |
| 'prompts': [] | |
| } | |
| estadisticas[modelo]['total_prompts'] += 1 | |
| estadisticas[modelo]['tiempos_totales'].append(resultado['tiempo_promedio']) | |
| estadisticas[modelo]['prompts'].append(resultado) | |
| # Calcular promedios generales | |
| for modelo, data in estadisticas.items(): | |
| data['avg_general'] = sum(data['tiempos_totales']) / len(data['tiempos_totales']) | |
| data['mejor_tiempo'] = min(data['tiempos_totales']) | |
| data['peor_tiempo'] = max(data['tiempos_totales']) | |
| self.metrics = estadisticas | |
| return estadisticas | |
| def mostrar_resultados(self): | |
| """Mostrar resultados de la comparativa""" | |
| if not self.metrics: | |
| print("❌ No hay métricas para mostrar. Ejecuta primero generar_estadisticas()") | |
| return | |
| print("=" * 80) | |
| print("📊 COMPARATIVA DE MODELOS OLLAMA") | |
| print("=" * 80) | |
| modelos_ordenados = sorted(self.metrics.items(), key=lambda x: x[1]['avg_general']) | |
| for i, (modelo, data) in enumerate(modelos_ordenados, 1): | |
| emoji = "🥇" if i == 1 else "🥈" if i == 2 else "📊" | |
| print(f"\n{emoji} {modelo}:") | |
| print(f" Tiempo promedio: {data['avg_general']:.3f} segundos") | |
| print(f" Mejor tiempo: {data['mejor_tiempo']:.3f} segundos") | |
| print(f" Peor tiempo: {data['peor_tiempo']:.3f} segundos") | |
| print(f" Prompts probados: {data['total_prompts']}") | |
| def generar_grafico(self, filename: str = "comparativa_modelos.png"): | |
| """Generar gráfico de comparativa""" | |
| if not self.metrics: | |
| print("❌ No hay métricas para graficar") | |
| return | |
| modelos = list(self.metrics.keys()) | |
| promedios = [self.metrics[modelo]['avg_general'] for modelo in modelos] | |
| plt.figure(figsize=(12, 8)) | |
| # Gráfico de barras | |
| bars = plt.bar(modelos, promedios, | |
| color=['skyblue', 'lightcoral', 'lightgreen', 'gold']) | |
| # Añadir valores en las barras | |
| for bar, valor in zip(bars, promedios): | |
| plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01, | |
| f'{valor:.2f}s', ha='center', va='bottom', fontweight='bold') | |
| plt.title('Comparativa de Tiempos de Respuesta - Modelos Ollama', fontsize=16, fontweight='bold') | |
| plt.ylabel('Tiempo Promedio (segundos)', fontsize=12) | |
| plt.xlabel('Modelos', fontsize=12) | |
| plt.xticks(rotation=45, ha='right') | |
| plt.grid(axis='y', alpha=0.3) | |
| # Ajustar layout y guardar | |
| plt.tight_layout() | |
| plt.savefig(filename, dpi=300, bbox_inches='tight') | |
| print(f"📈 Gráfico guardado como: {filename}") | |
| plt.show() | |
| def guardar_resultados(self, filename: str = "resultados_comparativa.json"): | |
| """Guardar resultados en archivo JSON""" | |
| datos_guardar = { | |
| 'fecha': datetime.now().isoformat(), | |
| 'resultados': self.results, | |
| 'estadisticas': self.metrics, | |
| 'resumen': { | |
| 'modelo_mas_rapido': min(self.metrics.items(), key=lambda x: x[1]['avg_general'])[0], | |
| 'modelo_mas_lento': max(self.metrics.items(), key=lambda x: x[1]['avg_general'])[0], | |
| 'diferencia_porcentual': self._calcular_diferencia_porcentual() | |
| } | |
| } | |
| with open(filename, 'w', encoding='utf-8') as f: | |
| json.dump(datos_guardar, f, indent=2, ensure_ascii=False) | |
| print(f"💾 Resultados guardados en: {filename}") | |
| def _calcular_diferencia_porcentual(self): | |
| """Calcular diferencia porcentual entre modelos""" | |
| if len(self.metrics) < 2: | |
| return {} | |
| modelos = list(self.metrics.keys()) | |
| diffs = {} | |
| for i in range(len(modelos)): | |
| for j in range(i + 1, len(modelos)): | |
| modelo1, modelo2 = modelos[i], modelos[j] | |
| avg1 = self.metrics[modelo1]['avg_general'] | |
| avg2 = self.metrics[modelo2]['avg_general'] | |
| if avg1 < avg2: | |
| mas_rapido, mas_lento = modelo1, modelo2 | |
| diff_porcentual = ((avg2 - avg1) / avg1) * 100 | |
| else: | |
| mas_rapido, mas_lento = modelo2, modelo1 | |
| diff_porcentual = ((avg1 - avg2) / avg2) * 100 | |
| diffs[f"{mas_rapido}_vs_{mas_lento}"] = { | |
| 'mas_rapido': mas_rapido, | |
| 'diferencia_porcentual': f"{diff_porcentual:.1f}%", | |
| 'tiempo_ahorro': f"{abs(avg1 - avg2):.3f}s por prompt" | |
| } | |
| return diffs | |
| # Configuración de la comparativa | |
| def main(): | |
| # Verificar que los modelos están disponibles | |
| print("🔍 Verificando modelos disponibles...") | |
| try: | |
| modelos_disponibles = [model['model'] for model in ollama.list()['models']] | |
| print(f"✅ Modelos encontrados: {modelos_disponibles}") | |
| except Exception as e: | |
| print(f"❌ Error al listar modelos: {e}") | |
| return | |
| # Modelos a comparar | |
| MODELOS_A_COMPARAR = ['codellama:latest', 'gpt-oss:latest'] | |
| # Verificar que los modelos existen | |
| modelos_faltantes = [modelo for modelo in MODELOS_A_COMPARAR if modelo not in modelos_disponibles] | |
| if modelos_faltantes: | |
| print(f"❌ Modelos faltantes: {modelos_faltantes}") | |
| print(" Descarga con: ollama pull nombre_del_modelo") | |
| return | |
| # Prompts para testing | |
| PROMPTS_PRUEBA = [ | |
| "Explica qué es Python en 3 oraciones", | |
| "Genera una función en Python que calcule números primos", | |
| "¿Cuáles son las ventajas de usar TypeScript sobre JavaScript?", | |
| "Escribe un código para conectarse a una API REST en Python", | |
| "Explica el concepto de machine learning para principiantes", | |
| "Cómo optimizar una consulta SQL con múltiples JOINs", | |
| "Genera un ejemplo de patrón de diseño Singleton en Java", | |
| "¿Qué es la programación funcional y cuáles son sus beneficios?", | |
| "Escribe un script Bash para backup automático", | |
| "Explica la diferencia entre HTTP/1.1 y HTTP/2" | |
| ] | |
| # Crear comparador y ejecutar pruebas | |
| comparador = ModelComparator() | |
| print("\n" + "="*80) | |
| print("🎯 INICIANDO PRUEBAS DE PERFORMANCE") | |
| print("="*80) | |
| resultados = comparador.comparar_modelos(MODELOS_A_COMPARAR, PROMPTS_PRUEBA, iteraciones=2) | |
| # Generar y mostrar estadísticas | |
| estadisticas = comparador.generar_estadisticas() | |
| comparador.mostrar_resultados() | |
| # Generar gráfico y guardar resultados | |
| comparador.generar_grafico() | |
| comparador.guardar_resultados() | |
| # Mostrar diferencia porcentual | |
| diffs = comparador._calcular_diferencia_porcentual() | |
| if diffs: | |
| print(f"\n📐 DIFERENCIAS PORCENTUALES:") | |
| for comparacion, data in diffs.items(): | |
| print(f" {comparacion}: {data['diferencia_porcentual']} más rápido") | |
| if __name__ == "__main__": | |
| main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment