En esta guía sobre Mezcla de expertos, aprenderás:
- Qué es el ME y en qué se diferencia de los modelos tradicionales
- Ventajas de su uso
- Un tutorial paso a paso sobre cómo aplicarlo
Sumerjámonos.
¿Qué es el ME?
Una mezcla de expertos (MoE, Mixture of Experts) es una arquitectura de aprendizaje automático que combina varios submodelos especializados -los “expertos”- dentro de un sistema más amplio. Cada experto aprende a manejar distintos aspectos de una tarea o distintos tipos de datos.
Un componente fundamental de esta arquitectura es la “red de compuertas” o “enrutador”. Este componente decide qué experto, o combinación de expertos, debe procesar una entrada específica. La red también asigna pesos a los resultados de cada experto. Las ponderaciones son como puntuaciones, ya que muestran cuánta influencia debe tener el resultado de cada experto.
En términos sencillos, la red de compuerta utiliza pesos para ajustar la contribución de cada experto a la respuesta final. Para ello, tiene en cuenta las características específicas de la entrada. Esto permite al sistema manejar muchos tipos de datos mejor de lo que podría hacerlo un único modelo.
Diferencias entre el ME y los modelos densos tradicionales
En el contexto de las redes neuronales, un modelo denso tradicional funciona de un modo distinto al ME. Para cualquier dato que se le introduzca, el modelo denso utiliza todos sus parámetros internos para realizar los cálculos. De este modo, cada parte de su maquinaria computacional se activa para cada entrada.
El punto principal es que, en los modelos densos, todas las partes se activan para cada tarea. Esto contrasta con el ME, que sólo activa las subsecciones expertas relevantes.
A continuación se exponen las principales diferencias entre los modelos Moe y denso:
- Utilización de parámetros:
- Modelo denso: Para cualquier entrada dada, el modelo utiliza todos los parámetros en el cálculo.
- Modelo ME: Para cualquier entrada dada, el modelo utiliza sólo los parámetros del experto o expertos seleccionados y la red de compuertas. Por lo tanto, si un modelo MoE tiene un gran número de parámetros, sólo activa una fracción de estos parámetros para cualquier cálculo.
- Coste computacional:
- Modelo denso: La cantidad de cálculo para una capa densa es fija para cada entrada, ya que todas sus partes están siempre ocupadas.
- Modelo MoE: El coste computacional de procesar una entrada a través de una capa MoE puede ser inferior al de una capa densa de tamaño total de parámetros comparable. Esto se debe a que sólo un subconjunto del modelo -los expertos elegidos- realiza el trabajo. Esto permite a los modelos MoE escalar a un número mucho mayor de parámetros totales sin un aumento proporcional del coste computacional para cada entrada individual.
- Especialización y aprendizaje:
- Modelo denso: Todas las partes de una capa densa aprenden a contribuir al procesamiento de todos los tipos de entradas que encuentra.
- Modelo ME: Las distintas redes de expertos pueden aprender a especializarse. Por ejemplo, un experto puede llegar a ser bueno procesando preguntas sobre historia, mientras que otro se especializa en conceptos científicos. La red de compuertas aprende a identificar el tipo de entrada y a dirigirla a los expertos más adecuados. Esto puede dar lugar a un procesamiento más matizado y eficaz.
Ventajas de la arquitectura mixta de expertos
La arquitectura MoE es muy relevante en la IA moderna, sobre todo cuando se trata de LLM. La razón es que ofrece una forma de aumentar la capacidad de un modelo, que es su habilidad para aprender y almacenar información, sin un aumento proporcional del coste computacional durante su uso.
Las principales ventajas de la ME en la IA incluyen:
- Reducción de la latencia de inferencia: Los modelos MoE pueden reducir el tiempo necesario para generar una predicción o un resultado, lo que se denomina latencia de inferencia. Esto ocurre gracias a su capacidad para activar solo a los expertos más relevantes.
- Mejora de la escalabilidad y la eficiencia del entrenamiento: Puede aprovechar el paralelismo de las arquitecturas MoE durante el proceso de formación de IA. Diferentes expertos pueden entrenarse simultáneamente en diversos subconjuntos de datos o tareas especializadas. Esto puede acelerar la convergencia y el tiempo de entrenamiento.
- Mejora de la modularidad y la capacidad de mantenimiento de los modelos: La naturaleza discreta de las subredes de expertos facilita un enfoque modular del desarrollo y mantenimiento del modelo. Los expertos individuales pueden actualizarse, reentrenarse o sustituirse por versiones mejoradas de forma independiente, sin necesidad de reentrenar todo el modelo. Esto simplifica la integración de nuevos conocimientos o capacidades y permite intervenciones más específicas si el rendimiento de un experto concreto se deteriora.
- Potencial para aumentar la interpretabilidad: La especialización de los expertos puede ofrecer una visión más clara de los procesos de toma de decisiones del modelo. Analizar qué expertos se activan sistemáticamente para entradas específicas puede proporcionar pistas sobre cómo el modelo ha aprendido a dividir el espacio del problema y a atribuir relevancia. Esta característica ofrece una vía potencial para comprender mejor los comportamientos complejos del modelo en comparación con las redes densas monolíticas.
- Mayor eficiencia energética a escala: Los modelos basados en MoE pueden lograr un menor consumo de energía por consulta en comparación con los modelos densos tradicionales. Esto se debe a la activación dispersa de parámetros durante la inferencia, ya que solo utilizan una fracción de los parámetros disponibles por entrada.
Cómo implantar el ME: Guía paso a paso
En esta sección del tutorial, aprenderá a utilizar MoE. En concreto, utilizará un conjunto de datos que contiene noticias deportivas. El MoE aprovechará dos expertos basados en los siguientes modelos:
sshleifer/distilbart-cnn-6-6
: Para resumir el contenido de cada noticia.distilbert-base-uncased-finetuned-sst-2-espanol
: Calcular el sentimiento de cada noticia. En el análisis de sentimiento, “sentimiento” se refiere al tono emocional, la opinión o la actitud expresada en un texto. El resultado puede ser:- Positivo: Expresa opiniones favorables, felicidad o satisfacción.
- Negativa: Expresa opiniones desfavorables, tristeza, enfado o insatisfacción.
- Neutro: No expresa emociones ni opiniones fuertes, a menudo se basa en hechos.
Al final del proceso, cada noticia se guardará en un archivo JSON que contendrá:
- El ID, el titular y la URL.
- El resumen del contenido.
- El sentimiento del contenido con la puntuación de confianza.
El conjunto de datos que contiene las noticias puede recuperarse utilizando las API Web Scraper de Bright Data, puntos finales de raspado especializados para recuperar datos web estructurados de más de 100 dominios en tiempo real.
El conjunto de datos que contiene los datos JSON de entrada puede generarse utilizando el código de nuestra guía “Understanding Vector Databases: El motor de la IA moderna“. En concreto, consulta el paso 1 del capítulo “Integración práctica: Guía paso a paso”.
El conjunto de datos JSON de entrada -denominado news-data.json- contiene
una matriz de noticias como la que se muestra a continuación:
[
{
"id": "c787dk9923ro",
"url": "https://www.bbc.com/sport/tennis/articles/c787dk9923ro",
"author": "BBC",
"headline": "Wimbledon plans to increase 'Henman Hill' capacity and accessibility",
"topics": [
"Tennis"
],
"publication_date": "2025-04-03T11:28:36.326Z",
"content": "Wimbledon is planning to renovate its iconic 'Henman Hill' and increase capacity for the tournament's 150th anniversary. Thousands of fans have watched action on a big screen from the grass slope which is open to supporters without show-court tickets. The proposed revamp - which has not yet been approved - would increase the hill's capacity by 20% in time for the 2027 event and increase accessibility. It is the latest change planned for the All England Club, after a 39-court expansion was approved last year. Advertisement "It's all about enhancing this whole area, obviously it's become extremely popular but accessibility is difficult for everyone," said four-time Wimbledon semi-finalist Tim Henman, after whom the hill was named. "We are always looking to enhance wherever we are on the estate. This is going to be an exciting project."",
"videos": [],
"images": [
{
"image_url": "https://ichef.bbci.co.uk/ace/branded_sport/1200/cpsprodpb/31f9/live/0f5b2090-106f-11f0-b72e-6314f702e779.jpg",
"image_description": "Main image"
},
{
"image_url": "https://ichef.bbci.co.uk/ace/standard/2560/cpsprodpb/31f9/live/0f5b2090-106f-11f0-b72e-6314f702e779.jpg",
"image_description": "A render of planned improvements to Wimbledon's Henman Hill"
}
],
"related_articles": [
{
"article_title": "Live scores, results and order of playLive scores, results and order of play",
"article_url": "https://www.bbc.com/sport/tennis/scores-and-schedule"
},
{
"article_title": "Get tennis news sent straight to your phoneGet tennis news sent straight to your phone",
"article_url": "https://www.bbc.com/sport/articles/cl5q9dk9jl3o"
}
],
"keyword": null,
"timestamp": "2025-05-19T15:03:16.568Z",
"input": {
"url": "https://www.bbc.com/sport/tennis/articles/c787dk9923ro",
"keyword": ""
}
},
// omitted for brevity...
]
Sigue las instrucciones que aparecen a continuación y construye tu ejemplo de ME.
Requisitos previos y dependencias
Para replicar este tutorial, debes tener Python 3.10.1 o superior instalado en tu máquina.
Supongamos que llamas a la carpeta principal de tu proyecto moe_project/
. Al final de este paso, la carpeta tendrá la siguiente estructura:
moe_project/
├── venv/
├── news-data.json
└── moe_analysis.py
Dónde:
venv/
contiene el entorno virtual de Python.news-data.json
es el archivo JSON de entrada que contiene los datos de noticias que ha obtenido con Web Scraper API.moe_analysis.py
es el archivo Python que contiene la lógica de codificación.
Puede crear el directorio del entorno virtual venv/
de la siguiente manera:
python -m venv venv
Para activarlo, en Windows, ejecute
venvScriptsactivate
De forma equivalente, en macOS y Linux, ejecute:
source venv/bin/activate
En el entorno virtual activado, instale las dependencias con:
pip install transformers torch
Estas bibliotecas son:
transformers
: la biblioteca de Hugging Face para modelos de aprendizaje automático de última generación.torch
: PyTorch, un marco de aprendizaje automático de código abierto.
Paso 1: Instalación y configuración
Inicializa el archivo moe_analysis.
py importando las librerías necesarias y configurando algunas constantes:
import json
from transformers import pipeline
# Define the input JSON file
JSON_FILE = "news-data.json"
# Specify the model for generating summaries
SUMMARIZATION_MODEL = "sshleifer/distilbart-cnn-6-6"
# Specify the model for analyzing sentiment
SENTIMENT_MODEL = "distilbert-base-uncased-finetuned-sst-2-english"
Este código define:
- El nombre del archivo JSON de entrada con las noticias raspadas.
- Los modelos a ues para los expertos.
Perfecto. Tienes lo que se necesita para empezar con MoE en Python.
Paso 2: Definir el experto en resumen de noticias
Este paso consiste en crear una clase que encapsule la funcionalidad del experto para resumir las noticias:
class NewsSummarizationLLMExpert:
def __init__(self, model_name=SUMMARIZATION_MODEL):
self.model_name = model_name
self.summarizer = None
# Initialize the summarization pipeline
self.summarizer = pipeline(
"summarization",
model=self.model_name,
tokenizer=self.model_name,
)
def analyze(self, article_content, article_headline=""):
# Call the summarizer pipeline with the article content
summary_outputs = self.summarizer(
article_content,
max_length=300,
min_length=30,
do_sample=False
)
# Extract the summary text from the pipeline's output
summary = summary_outputs[0]["summary_text"]
return { "summary": summary }
El código anterior:
- Inicializa la canalización de resumen con el método
pipeline()
de Hugging Face. - Define cómo el experto en resúmenes debe procesar un artículo con el método
analyze()
.
Muy bien. Acabas de crear el primer experto en la arquitectura del ME que se encarga de resumir las noticias.
Paso nº 3: Definir el experto en análisis de sentimiento
De forma similar al experto en resumen, defina una clase especializada para realizar el análisis de sentimiento de las noticias:
class SentimentAnalysisLLMExpert:
def __init__(self, model_name=SENTIMENT_MODEL):
self.model_name = model_name
self.sentiment_analyzer = None
# Initialize the sentiment analysis pipeline
self.sentiment_analyzer = pipeline(
"sentiment-analysis",
model=self.model_name,
tokenizer=self.model_name,
)
def analyze(self, article_content, article_headline=""):
# Define max tokens
max_chars_for_sentiment = 2000
# Truncate the content if it exceeds the maximum limit
truncated_content = article_content[:max_chars_for_sentiment]
# Call the sentiment analyzer pipeline
sentiment_outputs = self.sentiment_analyzer(truncated_content)
# Extract the sentiment label
label = sentiment_outputs[0]["label"]
# Extract the sentiment score
score = sentiment_outputs[0]["score"]
return { "sentiment_label": label, "sentiment_score": score }
Este fragmento:
- Inicializa el canal de análisis de sentimiento con el método
pipeline()
. - Define el método
analyze()
para realizar el análisis de sentimiento. También devuelve la etiqueta de sentimiento -negativa o positiva- y la puntuación de confianza.
Muy bien. Ahora tienes otro experto que calcula y expresa el sentimiento del texto de la noticia.
Paso nº 4: Implantar la red de compuertas
Ahora hay que definir la lógica de la red de compuertas para encaminar a los expertos:
def route_to_experts(item_data, experts_registry):
chosen_experts = []
# Select the summarizer and sentiment analyzer
chosen_experts.append(experts_registry["summarizer"])
chosen_experts.append(experts_registry["sentiment_analyzer"])
return chosen_experts
En esta aplicación, la red de compuertas es sencilla. Siempre utiliza ambos expertos para cada noticia, pero lo hace de forma secuencial:
- Resume el texto.
- Calcula el sentimiento.
Nota: La red de compuertas es bastante simple en este ejemplo. Al mismo tiempo, si se hubiera querido alcanzar el mismo objetivo utilizando un único modelo más amplio, se habría necesitado un cálculo significativamente mayor. En cambio, los dos expertos sólo se aprovechan para las tareas que les son relevantes. Esto la convierte en una aplicación sencilla pero eficaz de la arquitectura de Mezcla de Expertos.
En otros escenarios, esta parte del proceso podría mejorarse entrenando un modelo ML para aprender cómo y cuándo activar a un experto específico. Esto permitiría a la red de compuertas responder de forma dinámica.
Fantástico. La lógica de la red de compuertas está configurada y lista para funcionar.
Paso 5: Lógica de organización principal para el tratamiento de datos de noticias
Defina la función central que gestiona todo el flujo de trabajo definido por la siguiente tarea:
- Cargar el conjunto de datos JSON.
- Inicializar los dos expertos.
- Iterar a través de las noticias.
- Diríjalos a los expertos elegidos.
- Recoge los resultados.
Puedes hacerlo con el siguiente código:
def process_news_json_with_moe(json_filepath):
# Open and load news items from the JSON file
with open(json_filepath, "r", encoding="utf-8") as f:
news_items = json.load(f)
# Create a dictionary to hold instances of expert classes
experts_registry = {
"summarizer": NewsSummarizationLLMExpert(),
"sentiment_analyzer": SentimentAnalysisLLMExpert()
}
# List to store the analysis results
all_results = []
# Iterate through each news item in the loaded data
for i, news_item in enumerate(news_items):
print(f"n--- Processing Article {i+1}/{len(news_items)} ---")
# Extract relevant data from the news item
id = news_item.get("id")
headline = news_item.get("headline")
content = news_item.get("content")
url = news_item.get("url")
# Print progress
print(f"ID: {id}, Headline: {headline[:70]}...")
# Use the gating network to determine the expert to use
active_experts = route_to_experts(news_item, experts_registry)
# Prepare a dictionary to store the analysis results
news_item_analysis_results = {
"id": id,
"headline": headline,
"url": url,
"analyses": {}
}
# Iterate through the experts and apply their analysis
for expert_instance in active_experts:
expert_name = expert_instance.__class__.__name__ # Get the class name of the expert
try:
# Call the expert's analyze method
analysis_result = expert_instance.analyze(article_content=content, article_headline=headline)
# Store the result under the expert's name
news_item_analysis_results["analyses"][expert_name] = analysis_result
except Exception as e:
# Handle any errors during analysis by a specific expert
print(f"Error during analysis with {expert_name}: {e}")
news_item_analysis_results["analyses"][expert_name] = { "error": str(e) }
# Add the current item's results to the overall list
all_results.append(news_item_analysis_results)
return all_results
En este fragmento:
- El bucle
for
itera sobre todas las noticias cargadas. - El bloque
try-except
realiza el análisis y gestiona los errores que puedan producirse. En este caso, los errores que pueden producirse se deben principalmente a los parámetrosmax_length
ymax_chars_for_sentiment
definidos en las funciones anteriores. Dado que no todo el contenido recuperado tiene la misma longitud, la gestión de errores es fundamental para manejar las excepciones con eficacia.
Allá vamos. Has definido la función de orquestación de todo el proceso.
Paso nº 6: Iniciar la función de tratamiento
Como parte final del script, tienes que ejecutar la función principal de procesamiento y luego guardar los análisis en un archivo JSON de salida como se indica a continuación:
# Call the main processing function with the input JSON file
final_analyses = process_news_json_with_moe(JSON_FILE)
print("nn--- MoE Analysis Complete ---")
# Write the final analysis results to a new JSON file
with open("analyzed_news_data.json", "w", encoding="utf-8") as f_out:
json.dump(final_analyses, f_out, indent=4, ensure_ascii=False)
En el código anterior:
- La variable
final_analyses
llama a la función para procesar los datos con MoE. - Los datos analizados se almacenan en el archivo de salida
analyzed_news_data.json
.
¡Et voilà! Se finaliza todo el guión, se analizan los datos y se guardan.
Paso 7: Póngalo todo junto y ejecute el código
A continuación se muestra lo que el archivo moe_analysis.py
debe contener ahora:
import json
from transformers import pipeline
# Define the input JSON file
JSON_FILE = "news-data.json"
# Specify the model for generating summaries
SUMMARIZATION_MODEL = "sshleifer/distilbart-cnn-6-6"
# Specify the model for analyzing sentiment
SENTIMENT_MODEL = "distilbert-base-uncased-finetuned-sst-2-english"
# Define a class representing an expert for news summarization
class NewsSummarizationLLMExpert:
def __init__(self, model_name=SUMMARIZATION_MODEL):
self.model_name = model_name
self.summarizer = None
# Initialize the summarization pipeline
self.summarizer = pipeline(
"summarization",
model=self.model_name,
tokenizer=self.model_name,
)
def analyze(self, article_content, article_headline=""):
# Call the summarizer pipeline with the article content
summary_outputs = self.summarizer(
article_content,
max_length=300,
min_length=30,
do_sample=False
)
# Extract the summary text from the pipeline's output
summary = summary_outputs[0]["summary_text"]
return { "summary": summary }
# Define a class representing an expert for sentiment analysis
class SentimentAnalysisLLMExpert:
def __init__(self, model_name=SENTIMENT_MODEL):
self.model_name = model_name
self.sentiment_analyzer = None
# Initialize the sentiment analysis pipeline
self.sentiment_analyzer = pipeline(
"sentiment-analysis",
model=self.model_name,
tokenizer=self.model_name,
)
def analyze(self, article_content, article_headline=""):
# Define max tokens
max_chars_for_sentiment = 2000
# Truncate the content if it exceeds the maximum limit
truncated_content = article_content[:max_chars_for_sentiment]
# Call the sentiment analyzer pipeline
sentiment_outputs = self.sentiment_analyzer(truncated_content)
# Extract the sentiment label
label = sentiment_outputs[0]["label"]
# Extract the sentiment score
score = sentiment_outputs[0]["score"]
return { "sentiment_label": label, "sentiment_score": score }
# Define a gating network
def route_to_experts(item_data, experts_registry):
chosen_experts = []
# Select the summarizer and sentiment analyzer
chosen_experts.append(experts_registry["summarizer"])
chosen_experts.append(experts_registry["sentiment_analyzer"])
return chosen_experts
# Main function to manage the orchestration process
def process_news_json_with_moe(json_filepath):
# Open and load news items from the JSON file
with open(json_filepath, "r", encoding="utf-8") as f:
news_items = json.load(f)
# Create a dictionary to hold instances of expert classes
experts_registry = {
"summarizer": NewsSummarizationLLMExpert(),
"sentiment_analyzer": SentimentAnalysisLLMExpert()
}
# List to store the analysis results
all_results = []
# Iterate through each news item in the loaded data
for i, news_item in enumerate(news_items):
print(f"n--- Processing Article {i+1}/{len(news_items)} ---")
# Extract relevant data from the news item
id = news_item.get("id")
headline = news_item.get("headline")
content = news_item.get("content")
url = news_item.get("url")
# Print progress
print(f"ID: {id}, Headline: {headline[:70]}...")
# Use the gating network to determine the expert to use
active_experts = route_to_experts(news_item, experts_registry)
# Prepare a dictionary to store the analysis results
news_item_analysis_results = {
"id": id,
"headline": headline,
"url": url,
"analyses": {}
}
# Iterate through the experts and apply their analysis
for expert_instance in active_experts:
expert_name = expert_instance.__class__.__name__ # Get the class name of the expert
try:
# Call the expert's analyze method
analysis_result = expert_instance.analyze(article_content=content, article_headline=headline)
# Store the result under the expert's name
news_item_analysis_results["analyses"][expert_name] = analysis_result
except Exception as e:
# Handle any errors during analysis by a specific expert
print(f"Error during analysis with {expert_name}: {e}")
news_item_analysis_results["analyses"][expert_name] = { "error": str(e) }
# Add the current item's results to the overall list
all_results.append(news_item_analysis_results)
return all_results
# Call the main processing function with the input JSON file
final_analyses = process_news_json_with_moe(JSON_FILE)
print("nn--- MoE Analysis Complete ---")
# Write the final analysis results to a new JSON file
with open("analyzed_news_data.json", "w", encoding="utf-8") as f_out:
json.dump(final_analyses, f_out, indent=4, ensure_ascii=False)
¡Genial! En unas 130 líneas de código, acabas de completar tu primer proyecto ME.
Ejecute el código con el siguiente comando:
python moe_analysis.py
La salida en el terminal debe contener:
# Omitted for brevity...
--- Processing Article 6/10 ---
ID: cdrgdm4ye53o, Headline: Japanese Grand Prix: Lewis Hamilton says he has 'absolute 100% faith' ...
--- Processing Article 7/10 ---
ID: czed4jk7eeeo, Headline: F1 engines: A return to V10 or hybrid - what's the future?...
Error during analysis with NewsSummarizationLLMExpert: index out of range in self
--- Processing Article 8/10 ---
ID: cy700xne614o, Headline: Monte Carlo Masters: Novak Djokovic beaten as wait for 100th title con...
Error during analysis with NewsSummarizationLLMExpert: index out of range in self
# Omitted for brevity...
--- MoE Analysis Complete ---
Cuando finalice la ejecución, aparecerá un archivo de salida analyzed_news_data.json
en la carpeta del proyecto. Ábralo y céntrese en una de las noticias. El campo de análisis
contendrá el resumen y los resultados del análisis de sentimiento producidos por los dos expertos:
Como puede ver, el enfoque del ME tiene:
- Resumía el contenido del artículo y lo recogía en el
sumario
. - Definido un sentimiento positivo con una confianza del 0,99.
Misión cumplida.
Conclusión
En este artículo, usted aprendió sobre MoE y cómo implementarlo en un escenario del mundo real a través de una sección paso a paso.
Si desea explorar más escenarios de ME y necesita datos frescos para hacerlo, Bright Data ofrece un conjunto de potentes herramientas y servicios diseñados para recuperar datos actualizados y en tiempo real de páginas web superando los obstáculos del scraping.
Estas soluciones incluyen:
- Web Unlocker: Una API que elude las protecciones anti-scraping y entrega HTML limpio de cualquier página web con el mínimo esfuerzo.
- Navegador de raspado: Un navegador controlable basado en la nube con renderizado JavaScript. Gestiona automáticamente CAPTCHAs, huellas digitales del navegador, reintentos y mucho más.
- API de Web Scraper: Puntos finales para el acceso programático a datos web estructurados de docenas de dominios populares.
Para otros escenarios de aprendizaje automático, explore también nuestro AI hub.
Regístrese ahora en Bright Data y comience su prueba gratuita para probar nuestras soluciones de scraping.