Neste guia sobre Mixture of Experts, você aprenderá:
- O que é o MoE e como ele difere dos modelos tradicionais
- Benefícios de seu uso
- Um tutorial passo a passo sobre como implementá-lo
Vamos mergulhar de cabeça!
O que é o MoE?
Um MoE(Mixture of Experts) é uma arquitetura de aprendizado de máquina que combina vários submodelos especializados – os “especialistas” – em um sistema maior. Cada especialista aprende a lidar com diferentes aspectos de uma tarefa ou tipos distintos de dados.
Um componente fundamental dessa arquitetura é a “rede de passagem” ou “roteador”. Esse componente decide qual especialista, ou combinação de especialistas, deve processar uma entrada específica. A rede de gating também atribui pesos aos resultados de cada especialista. Os pesos são como pontuações, pois mostram o grau de influência que o resultado de cada especialista deve ter.
Em termos simples, a rede de gating usa pesos para ajustar a contribuição de cada especialista para a resposta final. Para isso, ela considera os recursos específicos da entrada. Isso permite que o sistema lide com muitos tipos de dados melhor do que um único modelo poderia fazer.
Diferenças entre o MoE e os modelos densos tradicionais
No contexto das redes neurais, um modelo denso tradicional funciona de maneira diferente do MoE. Para qualquer informação que você inserir nele, o modelo denso usa todos os seus parâmetros internos para realizar cálculos. Assim, cada parte de seu mecanismo de computação é acionada para cada entrada.
O ponto principal é que, em modelos densos, todas as partes são ativadas para cada tarefa. Isso contrasta com o MoE, que ativa apenas as subseções especializadas relevantes.
Abaixo estão as principais diferenças entre os modelos Moe e denso:
- Uso de parâmetros:
- Modelo denso: Para qualquer entrada dada, o modelo usa todos os parâmetros no cálculo.
- Modelo MoE: Para qualquer entrada, o modelo usa apenas os parâmetros do(s) especialista(s) selecionado (s) e a rede de gating. Portanto, se um modelo MoE tiver um grande número de parâmetros, ele ativará apenas uma fração desses parâmetros para qualquer cálculo individual.
- Custo computacional:
- Modelo denso: A quantidade de computação de uma camada densa é fixa para cada entrada, pois todas as suas partes estão sempre envolvidas.
- Modelo MoE: O custo computacional do processamento de uma entrada por meio de uma camada MoE pode ser menor do que o de uma camada densa de tamanho total de parâmetro comparável. Isso ocorre porque apenas um subconjunto do modelo – os especialistas escolhidos – realiza o trabalho. Isso permite que os modelos MoE sejam dimensionados para um número muito maior de parâmetros totais sem um aumento proporcional no custo computacional de cada entrada individual.
- Especialização e aprendizado:
- Modelo denso: Todas as partes de uma camada densa aprendem a contribuir para o processamento de todos os tipos de entrada que encontram.
- Modelo MoE: Diferentes redes de especialistas podem aprender a se especializar. Por exemplo, um especialista pode se tornar bom em processar perguntas sobre história, enquanto outro se especializa em conceitos científicos. A rede de gating aprende a identificar o tipo de entrada e a encaminhá-la para os especialistas mais adequados. Isso pode levar a um processamento mais matizado e eficaz.
Benefícios da arquitetura de combinação de especialistas
A arquitetura MoE é altamente relevante na IA moderna, principalmente quando se trata de LLMs. O motivo é que ela oferece uma maneira de aumentar a capacidade de um modelo, que é sua capacidade de aprender e armazenar informações, sem um aumento proporcional no custo computacional durante o uso.
As principais vantagens do MoE na IA incluem:
- Latência de inferência reduzida: Os modelos de MoE podem reduzir o tempo necessário para gerar uma previsão ou saída, chamado de latência de inferência. Isso acontece graças à sua capacidade de ativar somente os especialistas mais relevantes.
- Aumento da escalabilidade e da eficiência do treinamento: Você pode aproveitar o paralelismo das arquiteturas MoE durante o processo de treinamento de IA. Diferentes especialistas podem ser treinados simultaneamente em diversos subconjuntos de dados ou tarefas especializadas. Isso pode levar a uma convergência e a um tempo de treinamento mais rápidos.
- Melhoria da modularidade e da capacidade de manutenção do modelo: A natureza discreta das sub-redes de especialistas facilita uma abordagem modular para o desenvolvimento e a manutenção do modelo. Especialistas individuais podem ser atualizados de forma independente, retreinados ou substituídos por versões aprimoradas sem a necessidade de um retreinamento completo de todo o modelo. Isso simplifica a integração de novos conhecimentos ou recursos e permite intervenções mais direcionadas se o desempenho de um especialista específico for prejudicado.
- Potencial para maior interpretabilidade: A especialização dos especialistas pode oferecer percepções mais claras sobre os processos de tomada de decisão do modelo. A análise de quais especialistas são ativados de forma consistente para entradas específicas pode fornecer pistas sobre como o modelo aprendeu a dividir o espaço do problema e a atribuir relevância. Essa característica oferece uma possível maneira de entender melhor os comportamentos complexos do modelo em comparação com as redes densas monolíticas.
- Maior eficiência energética em escala: Os modelos baseados em MoE podem atingir um consumo de energia menor por consulta em comparação com os modelos densos tradicionais. Isso se deve à ativação esparsa dos parâmetros durante a inferência, pois eles usam apenas uma fração dos parâmetros disponíveis por entrada.
Como implementar o MoE: Um guia passo a passo
Nesta seção do tutorial, você aprenderá a usar o MoE. Em particular, você usará um conjunto de dados contendo notícias esportivas. O MoE aproveitará dois especialistas com base nos seguintes modelos:
sshleifer/distilbart-cnn-6-6
: Para resumir o conteúdo de cada notícia.distilbert-base-uncased-finetuned-sst-2-english
: Para calcular o sentimento de cada notícia. Na análise de sentimento, “sentimento” refere-se ao tom emocional, à opinião ou à atitude expressa em um texto. O resultado pode ser:- Positivo: Expressa opiniões favoráveis, felicidade ou satisfação.
- Negativo: Expressa opiniões desfavoráveis, tristeza, raiva ou insatisfação.
- Neutro: Não expressa emoções ou opiniões fortes, geralmente é factual.
No final do processo, cada item de notícia será salvo em um arquivo JSON contendo:
- O ID, o título e o URL.
- O resumo do conteúdo.
- O sentimento do conteúdo com a pontuação de confiança.
O conjunto de dados que contém as notícias pode ser recuperado usando as APIs do Web Scraper da Bright Data, pontos de extremidade de raspagem especializados para recuperar dados estruturados da Web de mais de 100 domínios em tempo real.
O conjunto de dados que contém os dados JSON de entrada pode ser gerado usando o código em nosso guia “Understanding Vector Databases: O mecanismo por trás da IA moderna“. Especificamente, consulte a etapa 1 no capítulo “Integração prática: A Step-by-Step Guide” (Integração prática: um guia passo a passo).
O conjunto de dados JSON de entrada – denominado news-data.json - contém
uma matriz de itens de notícias, conforme abaixo:
[
{
"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...
]
Siga as instruções abaixo e crie seu exemplo de MoE!
Pré-requisitos e dependências
Para replicar este tutorial, você deve ter o Python 3.10.1 ou superior instalado em sua máquina.
Suponha que você chame a pasta principal do seu projeto de moe_project/
. No final desta etapa, a pasta terá a seguinte estrutura:
moe_project/
├── venv/
├── news-data.json
└── moe_analysis.py
Onde:
venv/
contém o ambiente virtual do Python.news-data.json
é o arquivo JSON de entrada que contém os dados de notícias que você extraiu com a API do Web Scraper.moe_analysis.py
é o arquivo Python que contém a lógica de codificação.
Você pode criar o diretório do ambiente virtual venv/
da seguinte forma:
python -m venv venv
Para ativá-lo, no Windows, execute:
venvScriptsactivate
De forma equivalente, no macOS e no Linux, execute:
source venv/bin/activate
No ambiente virtual ativado, instale as dependências com:
pip install transformers torch
Essas bibliotecas são:
transformers
: biblioteca da Hugging Face para modelos de aprendizado de máquina de última geração.torch
: PyTorch, uma estrutura de aprendizado de máquina de código aberto.
Etapa 1: Instalação e configuração
Inicialize o arquivo moe_analysis.py
importando as bibliotecas necessárias e configurando algumas 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"
Esse código define:
- O nome do arquivo JSON de entrada com as notícias extraídas.
- Os modelos são usados pelos especialistas.
Perfeito! Você tem o que é necessário para começar a usar o MoE em Python.
Etapa 2: Definir o especialista em resumo de notícias
Essa etapa envolve a criação de uma classe que encapsula a funcionalidade do especialista para resumir as notícias:
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 }
O código acima:
- Inicializa o pipeline de compactação com o método
pipeline()
do Hugging Face. - Define como o especialista em compactação deve processar um artigo com o método
analyze()
.
Ótimo! Você acabou de criar o primeiro especialista na arquitetura do MoE que se encarrega de resumir as notícias.
Etapa 3: Definir o especialista em análise de sentimentos
Semelhante ao especialista em resumo, defina uma classe especializada para realizar a análise de sentimento nas notícias:
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 trecho:
- Inicializa o pipeline de análise de sentimentos com o método
pipeline()
. - Define o método
analyze()
para executar a análise de sentimentos. Ele também retorna o rótulo do sentimento – negativo ou positivo – e a pontuação de confiança.
Muito bem! Agora você tem outro especialista que calcula e expressa o sentimento do texto na notícia.
Etapa nº 4: Implementar a rede de portas
Agora, você precisa definir a lógica por trás da rede de portas para rotear os especialistas:
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
Nessa implementação, a rede de gating é simples. Ela sempre usa os dois especialistas para cada item de notícia, mas o faz sequencialmente:
- Ele resume o texto.
- Ele calcula o sentimento.
Observação: A rede de gating é bastante simples neste exemplo. Ao mesmo tempo, se você quisesse atingir o mesmo objetivo usando um modelo único e maior, seria necessário um cálculo significativamente maior. Por outro lado, os dois especialistas são aproveitados apenas para as tarefas que são relevantes para eles. Isso o torna um aplicativo simples e eficaz da arquitetura Mixture of Experts.
Em outros cenários, essa parte do processo poderia ser aprimorada com o treinamento de um modelo de ML para aprender como e quando ativar um especialista específico. Isso permitiria que a rede de gating respondesse de forma dinâmica.
Fantástico! A lógica da rede de gating está configurada e pronta para operar.
Etapa 5: lógica de orquestração principal para processar dados de notícias
Defina a função principal que gerencia todo o fluxo de trabalho definido pela tarefa a seguir:
- Carregar o conjunto de dados JSON.
- Inicialize os dois especialistas.
- Iterar pelos itens de notícias.
- Encaminhe-os para os especialistas escolhidos.
- Colete os resultados.
Você pode fazer isso com o seguinte 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
Neste trecho:
- O loop
for
itera sobre todas as notícias carregadas. - O bloco
try-except
executa a análise e gerencia os erros que podem ocorrer. Nesse caso, os erros que podem ocorrer se devem principalmente aos parâmetrosmax_length
emax_chars_for_sentiment
definidos nas funções anteriores. Como nem todo o conteúdo recuperado tem o mesmo comprimento, o gerenciamento de erros é fundamental para o tratamento eficaz das exceções.
Aqui vamos nós! Você definiu a função de orquestração de todo o processo.
Etapa nº 6: Inicie a função de processamento
Como parte final do script, você deve executar a função de processamento principal e, em seguida, salvar as análises em um arquivo JSON de saída, como segue:
# 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)
No código acima:
- A variável
final_analyses
chama a função para processar os dados com o MoE. - Os dados analisados são armazenados no arquivo de saída
analyzed_news_data.json
.
E pronto! O script completo é finalizado, os dados são analisados e salvos.
Etapa nº 7: Junte tudo e execute o código
Veja abaixo o que o arquivo moe_analysis.py
deve conter agora:
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)
Excelente! Em cerca de 130 linhas de código, você acabou de concluir seu primeiro projeto do MoE.
Execute o código com o seguinte comando:
python moe_analysis.py
A saída no terminal deve conter:
# 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 ---
Quando a execução for concluída, um arquivo de saída analyzed_news_data.json
será exibido na pasta do projeto. Abra-o e concentre-se em um dos itens de notícias. O campo de análise
conterá o resumo e os resultados da análise de sentimento produzidos pelos dois especialistas:
Como você pode ver, a abordagem do MoE tem:
- Resumiu o conteúdo do artigo e o relatou em
resumo
. - Definiu um sentimento positivo com uma confiança de 0,99.
Missão concluída!
Conclusão
Neste artigo, você aprendeu sobre o MoE e como implementá-lo em um cenário do mundo real por meio de uma seção passo a passo.
Se você quiser explorar mais cenários do MoE e precisar de dados atualizados para isso, a Bright Data oferece um conjunto de ferramentas e serviços avançados projetados para recuperar dados atualizados e em tempo real de páginas da Web e, ao mesmo tempo, superar os obstáculos de raspagem.
Essas soluções incluem:
- Web Unlocker: Uma API que contorna as proteções antirrastreamento e fornece HTML limpo de qualquer página da Web com o mínimo de esforço.
- Navegador de raspagem: Um navegador controlável e baseado em nuvem com renderização de JavaScript. Ele lida automaticamente com CAPTCHAs, impressão digital do navegador, novas tentativas e muito mais para você.
- APIs do Web Scraper: Endpoints para acesso programático a dados estruturados da Web de dezenas de domínios populares.
Para outros cenários de aprendizado de máquina, explore também nosso hub de IA.
Inscreva-se agora na Bright Data e comece sua avaliação gratuita para testar nossas soluções de raspagem!