Lições de gerar 12 trilhões de tokens sintéticos — Bogdan Gaza, DatologyAI
Autoria: AI Engineer · Assistir no YouTube
Vídeo de autoria do canal indicado, não da IANIA; todos os direitos pertencem ao criador. Transcrição, resumo e tradução gerados automaticamente; o conteúdo no idioma original é preservado na versão em idioma original.
Idioma original: inglês
Vídeo original: Lessons from Generating 12 Trillion Synthetic Tokens — Bogdan Gaza, DatologyAI · Canal: AI Engineer · 20:28 · Assistir no YouTube
Tópicos: Dados, bancos de dados e embeddings, Inferência e otimização de modelos, Infraestrutura e hardware de IA, Modelos de IA
Bogdan Gaza, cofundador e CEO da DatologyAI, explica por que dados sintéticos são importantes diante da escassez de dados disponíveis na web para pré-treinamento. Ele apresenta a abordagem Beyond Web, que reformula documentos de alta qualidade para produzir grandes conjuntos de dados e, segundo os resultados mostrados, pode reduzir dados e compute necessários para atingir determinado desempenho. A palestra detalha desafios de engenharia encontrados ao escalar a geração de dados sintéticos, incluindo metadados no S3, instabilidade de GPUs, orquestração entre clusters e otimização de inference. A equipe passou de execuções limitadas a gerar cerca de 12 trilhões de tokens sintéticos para web, matemática e código.
Pontos-chave
Seção intitulada “Pontos-chave”- A quantidade de dados disponíveis na web é limitada, enquanto as execuções de pré-treinamento em grande escala exigem cada vez mais dados.
- A abordagem Beyond Web parte de documentos de alta qualidade e os reformula ou reestrutura, em vez de pedir a um modelo que gere dados sem referências.
- Dados sintéticos de alta qualidade podem permitir modelos menores ou menos tokens para atingir desempenho comparável, conforme os resultados apresentados.
- Buscar metadados de milhões de partições individualmente no S3 pode levar dias e deixar GPUs ociosas; agrupar as requisições reduziu o processamento estimado de 9 a 11 dias para cerca de duas horas.
- Partições de tamanho adequado e checkpointing ajudam a limitar o trabalho perdido quando um job falha.
- Orquestrar jobs em vários clusters requer planejar conjuntamente os recursos de CPU e GPU e agendar esses recursos de forma coordenada.
- Ajustar e comparar parâmetros de inference em lote pode melhorar significativamente o throughput; a equipe relatou ganhos de cerca de 40% com ajustes nos parâmetros de VLM.
- A equipe aumentou sua capacidade de cerca de 30 bilhões de tokens sintéticos em execuções limitadas para aproximadamente 12 trilhões de tokens em dados de web, matemática e código.
Capítulos
Seção intitulada “Capítulos”| Início | Capítulo | Resumo |
|---|---|---|
| 00:01 | Por que gerar dados sintéticos | Gaza apresenta a escassez de dados disponíveis na web e introduz a geração de dados sintéticos em escala de trilhões de tokens. |
| 04:08 | A receita Beyond Web | A abordagem parte de documentos de alta qualidade e os reformula para gerar dados sintéticos mais úteis que amostras sem referência. |
| 05:42 | Integração dos pipelines e dos clusters | A equipe descreve a migração de um fluxo de pesquisa separado para uma infraestrutura coordenada baseada em Kubernetes, Spark e Ray. |
| 09:21 | Gargalos de metadados em escala | A palestra explica como agrupar consultas ao S3 reduziu de 9 a 11 dias para cerca de duas horas a coleta de metadados. |
| 12:27 | Falhas de GPU e recuperação de jobs | Partições menores e checkpointing permitem retomar jobs com menos perda de progresso quando ocorrem falhas. |
| 15:04 | Orquestração entre clusters e inference | Gaza aborda o agendamento coordenado de CPU e GPU em vários clusters e a otimização dos parâmetros de inference em lote. |
| 19:14 | Escala alcançada e próximos passos | A equipe compara sua capacidade inicial, de cerca de 30 bilhões de tokens, com as execuções que chegaram a aproximadamente 12 trilhões. |
Citações
Seção intitulada “Citações”Você pode treinar modelos um pouco menores e obter o mesmo desempenho que obteria com modelos maiores usando dados sintéticos. — 03:07
De 11 dias para duas horas. — 11:56
Você precisa pensar em como agendar os recursos de CPU e GPU, especialmente para o mesmo tipo de job. — 17:40
Você pode obter ganhos de throughput de cerca de 40% apenas ajustando os parâmetros de VLM. — 18:10
Conceitos e entidades
Seção intitulada “Conceitos e entidades”- Bogdan Gaza (pessoa): Cofundador e CEO da DatologyAI, e palestrante sobre a geração de dados sintéticos em grande escala.
- DatologyAI (empresa): Empresa de curadoria de dados que ajuda clientes a selecionar conjuntos de dados para pré-treinamento e mid-training.
- Beyond Web (conceito): Receita de dados sintéticos que reformula ou reestrutura documentos de alta qualidade para criar conjuntos de dados de treinamento.
- Ray (ferramenta): Ferramenta usada pela equipe para executar e orquestrar jobs, inclusive os que utilizam GPUs.
- Kubernetes (ferramenta): Plataforma usada para executar e coordenar componentes dos pipelines em diferentes clusters.
- Amazon S3 (ferramenta): Camada de armazenamento usada para os dados e para acessar metadados das partições.
- VLM (ferramenta): Sistema mencionado para executar inference em lote e cujos parâmetros podem ser ajustados para aumentar o throughput.
- H100 (modelo): GPU citada como recurso dos clusters usados nas execuções de dados sintéticos e treinamento.
Tradução completa (pt-BR)
Seção intitulada “Tradução completa (pt-BR)”00:01 [música] Vamos fazer isso. Oi, pessoal, sejam bem-vindos à minha palestra. Sou Bogdan. Sou um dos cofundadores e CEO da DatologyAI. Hoje vamos falar sobre as lições de engenharia aprendidas ao escalar dados sintéticos para o pré-treinamento em escala de trilhões de tokens. Vamos ver. Então, por que precisamos de dados sintéticos, antes de mais nada? Bem, acontece que, com as leis de escala, meio que chegamos a um limite de dados. É preciso adicionar exponencialmente mais compute e exponencialmente mais dados para obter modelos que ficam cada vez melhores de forma mais ou menos linear. Então, chegamos a um ponto em que as execuções de pré-treinamento são enormes. Para fazer aquelas que realmente chegam, sei lá, ao nível de capacidades do Mythos, é preciso uma quantidade enorme de dados, e muitos deles não podem ser encontrados na web. A internet tem uma quantidade limitada de dados, mas podemos complementá-los com
00:32 dados sintéticos de alta qualidade. Então, sobre o que vamos falar hoje? Vamos falar sobre como fazer isso, antes de mais nada. Também vamos falar um pouco sobre Beyond Web, que é mais ou menos a nossa receita de dados sintéticos. Vamos falar das lições de engenharia da nossa experiência anterior na DatologyAI com execuções de dados sintéticos em escala de trilhões de tokens. Recentemente, concluímos uma execução com cerca de 12 trilhões de tokens. Isso abrange web, matemática e código. E vamos falar sobre o que aprendemos ao executar rodadas sintéticas absolutamente enormes.
01:03 E depois vamos falar sobre por que isso importa, antes de mais nada. Ótimo. Então, vamos começar. A forma como resolvemos o problema dos dados sintéticos na DatologyAI — e talvez seja melhor começar com uma breve apresentação da empresa — é como um serviço de curadoria de dados. Pensem em nós como uma refinaria de petróleo para seus conjuntos de dados de pré-treinamento e de treinamento intermediário. Trabalhamos com clientes, tanto startups quanto empresas, que nos procuram para ajudá-los com suas necessidades de dados de pré-treinamento e de
01:34 treinamento intermediário. Em geral, eles têm muitos dados e querem chegar aos melhores conjuntos de dados possíveis. Nós os ajudamos a identificar os pontos de dados da mais alta qualidade e, depois disso, passamos esses dados pela nossa receita de dados sintéticos, sobre a qual vamos falar hoje, para criar conjuntos de dados absolutamente enormes. Isso é um pouco sobre nós. Quanto à Beyond Web, essa é a nossa receita de dados sintéticos. Existem muitas maneiras de gerar dados sintéticos, mas a abordagem que usamos é bem diferente. Aqui estão alguns resultados de como fazemos isso.
02:05 Há dois gráficos. Talvez comecemos pelo primeiro. No eixo x, temos o tamanho do modelo, em bilhões de parâmetros: 1 bilhão, 3 bilhões e 8 bilhões. No eixo y, temos a acurácia. Pegamos vários conjuntos de dados, como Neotron Synth, Cosmopedia, QA rap e Red Pajama, e treinamos modelos nas escalas de 1B, 3B e 8B, usando também a receita que elaboramos para dados sintéticos, que chamamos de Beyond Web.
02:36 E o que vemos é que nossa receita de dados sintéticos iguala os resultados e, às vezes, até — neste caso, o ponto de dados de 3B iguala o ponto de dados de 8B no Neotron Synth. Isso significa que, usando dados sintéticos, você pode treinar modelos um pouco menores para obter o mesmo desempenho que teria com modelos maiores. Isso dá uma ideia da qualidade da nossa receita. A mesma coisa
03:07 aqui, quando falamos de desempenho. No eixo x, temos o número de tokens, em bilhões, e no eixo y, a acurácia média. O que mostramos é que igualamos o desempenho do Neotron Synth e do Cosmopedia usando, respectivamente, cerca de 2,7 vezes e 5,3 vezes menos tokens. Portanto, se você quiser treinar um modelo para alcançar o mesmo desempenho, pode fazer isso usando menos dados e, no geral, menos compute.
03:37 Em linhas gerais, Beyond Web é a forma como pensamos na nossa receita de dados sintéticos. O que fazemos são reformulações. Vemos o processo de geração de dados sintéticos como a identificação dos pontos de dados da mais alta qualidade no conjunto de dados do cliente e, em seguida, a reformulação ou reestruturação desses pontos de dados de várias maneiras. Esses resultados são um pouco antigos. Acho que a versão original foi publicada no fim do verão de 2025 e, neste momento, estamos muito, muito melhores do que isso.
04:08 E continuamos melhorando bastante. Então, como gerar dados sintéticos? Na forma mais simples, você tem algum tipo de conjunto de dados-alvo. Mais uma vez, fazemos reformulações ou reenquadramentos de documentos existentes. A ideia é que, se você simplesmente der um prompt a um modelo e disser: “Ei, gere um ponto de dados sintético”, ele vai apenas aprender os modos da distribuição em que os dados usados originalmente no treinamento se baseavam. Como mencionei antes, nossa abordagem é usar como semente algum tipo de documento existente. Então, identificamos documentos de alta qualidade
04:39 nos conjuntos de dados de treinamento do cliente e os passamos pelo nosso pipeline. No caso mais simples, temos um conjunto de dados-alvo. Imagine que ele possa ser texto ou texto e imagem. Na forma mais simples, são apenas vários prompts que colocamos como prefixo de vários documentos que identificamos. Você tem várias GPUs e, então, usa diferentes modelos para gerar dados sintéticos. Na prática, você tem certas expectativas sobre quanto tempo isso vai levar. Mas
05:10 na prática, o processo tem muito mais oscilações e é realmente difícil alcançar a vazão ideal que você espera obter das suas GPUs. Então, como lidamos com isso? Bem, por onde começamos? Começamos numa situação em que os dados sintéticos não estavam integrados ao nosso produto. Era algo que fazíamos em um contexto de pesquisa, num cluster que executa Slurm, separado do nosso pipeline principal, baseado em Kubernetes. Tínhamos esse sistema de duas vias, em que as equipes de produto e de pesquisa não usavam a mesma base de código. Isso era lento, propenso a erros e limitava a velocidade de desenvolvimento, além de levar à subutilização das nossas GPUs.
05:42 Temos um número determinado de GPUs, como todo mundo. E, em geral, queremos maximizar o uso delas, executando o treinamento e as rodadas de geração de dados sintéticos de forma integrada. Então, por onde começamos? Em geral, gostaríamos de executar tudo no Kubernetes. Grande parte do nosso pipeline usa Ray ou Spark. Hoje vamos falar de Ray, Kubernetes e VLM; esses são os componentes principais da nossa biblioteca de dados sintéticos
06:13 ou dos nossos pipelines de dados. Hoje, temos uma camada de orquestração em um cluster Kubernetes. Executamos Spark em outros clusters Kubernetes e mantemos o Aster Tracker, que é o nosso catálogo de dados, no cluster de controle original, onde tudo é coordenado. Todos os dados ficam armazenados no S3, que é a nossa camada de armazenamento. Desde que algo seja compatível com as APIs do S3, podemos executá-lo. De certa forma, tudo precisa ser executado no Kubernetes, porque nossos pipelines são implantados em todos os tipos de ambiente.
06:44 ou pipelines de dados, mais ou menos. Então, hoje, o que fazemos é ter uma camada de orquestração em um cluster do Kubernetes. Executamos o Spark em outros clusters do Kubernetes e mantemos o Aster Tracker, que é nosso catálogo de dados, no cluster de controle original, onde tudo é coordenado. Todos os dados são armazenados no S3, que é nossa camada de armazenamento. Desde que o sistema tenha APIs compatíveis com S3, podemos executá-lo. Então, de certa forma, tudo precisa ser executado no Kubernetes, porque nossos pipelines são implantados em todos os tipos de ambientes.
07:16 Pode ser AWS, pode ser GCP, pode ser on-prem etc. Queremos garantir que possamos executá-lo em qualquer ambiente Kubernetes. Separadamente, tínhamos esse cluster H100. Ele executava geração de dados sintéticos, treinamento, evals e várias outras coisas. Originalmente, tudo era orquestrado pelo Slurm. Mover dados entre esses dois clusters era um processo manual. Então, sempre que você gerava dados sintéticos no Slurm, precisava incluí-los no rastreador de ativos, no nosso catálogo de dados. Então, onde estamos agora? Em alguns aspectos, temos uma configuração parecida, com o cluster original
07:47 que faz o controle. Temos o cluster de computação, onde executamos jobs do Spark, e agora temos esse outro cluster de computação H100. No nosso caso, executamos tudo na AWS. Usamos o HyperPod. O HyperPod tem um produto chamado EKS on HyperPod. Basicamente, são vários clusters H100 na mesma spine, todos orquestrados pelo Kubernetes. Então, continuamos executando jobs do Spark e do Ray em capacidade sob demanda, com CPUs sob demanda e, às vezes, GPUs sob demanda — especialmente para coisas que não exigem H100s, que podemos executar assim —
08:18 e então orquestramos tudo de maneira parecida com a de antes: o Spark roda dentro do cluster Kubernetes dele, e o Ray roda no mesmo cluster para GPUs que não são H100. Para tudo que precisamos fazer em nós H100, usamos esse outro cluster Kubernetes. Também temos um scheduler de jobs que desenvolvemos internamente e que orquestra tudo isso. Se fizermos isso, poderemos executar experimentos rapidamente. Imagine que você possa executar uma espécie de curadoria, com vários jobs do Spark,
08:49 gerar vários dados sintéticos, depois iniciar um job de treinamento e, em seguida, executar um job de eval. Você pode orquestrar tudo isso em um único workflow, o que é bastante útil para nossa equipe de pesquisa. Isso coloca o fluxo de pesquisa e o fluxo de engenharia na mesma linha, na mesma infraestrutura, no mesmo código, no mesmo caminho. Certo. Então, onde estamos agora? Olha só, tenho uma reunião individual com alguém sobre isso. Onde estamos é que os dados sintéticos são uma parte central dos nossos workflows.
09:21 Fazemos experimentos o tempo todo. Executamos esse agendamento entre clusters. É muito mais rápido, muito mais confiável e podemos executá-lo em escala. Recentemente, fizemos uma geração massiva de dados sintéticos. Vamos falar um pouco das lições de engenharia que aprendemos com isso. Quais são os gargalos na escala de trilhões de tokens? Bem, antes de mais nada, a quantidade de dados de texto disponível na internet é bastante limitada. Na web, podemos encontrar cerca de 30 trilhões de tokens,
09:52 mais ou menos. Para imagens, há cerca de 12,8 bilhões em conjuntos como o DataComp. Para texto, geralmente começamos com conjuntos de dados existentes e de alta qualidade, como FineWeb, DCLM e Dolma. Podemos juntar tudo e obter esses grandes conjuntos de dados. Mas, nessa escala, geralmente tudo é armazenado em Parquet ou algum formato semelhante, e temos milhões de partições de dados. Se você tentar buscar todas elas no S3 em alta velocidade, pode sofrer limitação de taxa. E se
10:22 você executar isso no Ray, os metadados do Ray — e a forma como você os gerencia — podem se tornar um gargalo. Isso leva ao pior resultado possível: GPUs ociosas. Um gargalo que vimos inicialmente é o seguinte: temos o S3 e tentamos buscar os dados a partir do nosso Ray head. Ele tem algum tipo de armazenamento de metadados. Isso é bastante lento. Se uma solicitação leva 10 milissegundos e você está tentando fazer milhões e milhões delas,
10:54 digamos, para buscar os metadados, essas operações inicialmente são mais caras. Também há um limite de taxa; se você precisar fazer milhões delas, vai sofrer limitação de taxa, e seus workers ficarão bem lentos. Então, fizemos uma conta aproximada para preencher os metadados de trilhões e trilhões de tokens. Isso levaria cerca de 9 a 11 dias, o que é inaceitável, certo? Se você está executando isso, provavelmente está gastando milhões de dólares em computação. Não pode deixar tudo esperando
11:25 11 dias pela busca dos metadados. Então, a maneira como contornamos isso foi fazer solicitações em lote, em vez de acessar o S3 uma solicitação por vez. Você pode agrupá-las em lotes. O S3 oferece suporte a isso por meio das APIs. Assim, você pode fazer isso em grande escala aumentando o tamanho da página dos lotes até o limite
11:56 que o S3 permite, que é cerca de mil solicitações em uma lista. Isso reduz o tempo de processamento da API para cerca de duas horas para obter os metadados. Então, a primeira lição: saiba como você gerencia seus metadados e pense em como obter o estado dos seus buckets do S3 para o sistema de dados sintéticos que você usa, para que possa sequer começar a fazer isso em escala. De 11 dias para duas
12:27 horas. Essa é a primeira lição. Ótimo. A segunda é a instabilidade das GPUs. Sempre que você executa essas gerações de dados sintéticos em grande escala, é claro que vai encontrar algumas GPUs com problemas, certo? Isso significa que a máquina pode parar. A GPU pode estar com defeito. Coisas desse tipo. Tudo o que você espera que aconteça ao executar isso em escala vai acontecer. Isso leva à perda de progresso, ao desperdício de computação e a saídas parciais, por exemplo, se você
12:58 processar apenas metade do arquivo. E, claro, no fim das contas, você vai precisar de mais tempo de cluster, o que é sempre difícil de conseguir. Na nossa pipeline, fazemos isso assim: temos um job do Spark que gera os prompts junto com os documentos que precisamos reformular e os combina. Depois, iniciamos um job do Ray que realmente usa as GPUs. O problema é que existe um mapeamento um para um entre entrada e saída. É assim que geralmente estruturamos esse tipo de
13:30 job. Na prática, se suas partições forem muito grandes, você vai avançar bastante no processamento. Mas, se um job de reformulação em um nó, para um arquivo de uma partição, levar oito horas e a máquina parar nos últimos cinco minutos dessas oito horas, você perderá muito tempo. Então, você precisa pensar que ou faz checkpoints e, sempre que avança no processamento dentro dos
14:02 jobs de dados sintéticos, para periodicamente e grava esse progresso no S3, ou usa partições pequenas o bastante para tolerar esse tempo de inatividade. Portanto, você precisa pensar no tamanho das partições ou, de modo geral, implementar algum tipo de checkpoint. Fizemos um pouco de cada coisa: ajustamos o tamanho das partições e também criamos checkpoints para esses casos. Assim, sempre que um job falha, ele é executado novamente, mas o
14:33 A quantidade de tempo que perdemos é mínima e faz sentido para a configuração que temos. Então, em vez de falhas em tarefas que duram vários dias, agora temos novas tentativas recuperáveis, e funciona como esperado. Para recapitular: retomada da execução, algum tipo de idempotência, em que, sempre que você cria um checkpoint, pode sobrescrever o arquivo em que está salvando o checkpoint; e então você precisa de algum mecanismo para recuperação contínua e orquestração entre infraestruturas. No nosso caso, o cluster em que nós…
15:04 A curadoria de origem, em geral, nosso pipeline é executado em um local centralizado, e os clientes podem ter tarefas de dados sintéticos executadas em vários locais com GPU pelo mundo. Pode ser difícil conseguir muita capacidade em um único lugar, especialmente para dados sintéticos, em que você não precisa necessariamente de uma rede rápida entre os nós com GPU. Então, o que acontece é que você precisa conseguir orquestrar todas essas tarefas em vários clusters. Não é apenas um cluster com GPU com que você trabalha; são vários. O problema aqui é que…
15:35 Sempre que você tenta agendar essas tarefas, pode conseguir agendar os requisitos de CPU para suas tarefas do Ray, mas não necessariamente os requisitos de GPU no pool de GPU. Então, você precisa pensar em como agendar de alguma forma esses dois recursos. Agora, quando chega a próxima tarefa, você tem capacidade disponível no pool de GPU, mas não no pool de CPU. Em geral, sempre que você tenta…
16:06 fazer esse tipo de orquestração entre infraestruturas, precisa pensar no agendamento e em como realizá-lo de forma eficaz. Neste caso, como mencionei, chega um ponto em que você não consegue agendar com eficácia. Então, precisa pensar em como fazer isso da maneira adequada. No fim das contas, é algum tipo de problema de empacotamento em caixas. Como resolvemos isso? A configuração é a mesma de antes. Temos esse…
16:37 orquestrador que é executado em um cluster diferente. Temos o cluster de computação que executa Spark e as tarefas do Ray, que precisam principalmente de CPU, e depois temos o cluster com H100s. Ao agendar, temos pools dedicados para os recursos específicos de que você precisa nesses clusters. Se você precisa de Spark, pode ter um pool de Spark com CPUs e, então, reservar pools especiais para o head do Ray. Ao pensar em algum tipo de agendamento atômico…
17:08 você precisa considerar tanto os requisitos de CPU quanto os de GPU para fazer isso da forma ideal. Neste caso, como separamos esses dois recursos, quando temos mais requisitos de CPU para agendar, podemos agendar o head e o worker do Ray de forma mais atômica e não temos os problemas de antes. Então, tudo escala como esperado. Na orquestração entre infraestruturas, você precisa considerar vários provedores e várias nuvens em que executa isso…
17:40 Você precisa pensar no agendamento e garantir que, ao agendar recursos de CPU e GPU, especialmente para o mesmo tipo de tarefa, faça isso de uma forma que faça sentido. Por último, temos as otimizações de inference. Ao executar VLM ou SGLang, você precisa pensar nos hiperparâmetros usados nas tarefas. O que descobrimos é que é preciso ser bastante disciplinado com isso, fazer benchmarks, otimizar e ter um harness focado apenas nos parâmetros do VLM.
18:10 É possível obter muitos ganhos; neste caso, cerca de 40% a mais de throughput, apenas ajustando as flags do VLM e do SGLang. No nosso caso, usamos VLM. Agora também estamos testando HGLang. Fazemos muita inference em lote, que é bem diferente da inference online normal a que todos estão acostumados. Ao orquestrar isso por meio do VLM, você precisa garantir que tenha o tamanho de lote correto, a configuração correta de speculative decoding etc.
18:43 Se você fizer várias buscas em grade pelos parâmetros que precisa otimizar, verá que pode obter muitos resultados em termos de throughput. Para recapitular: ao tentar fazer isso, pense na escala em que está operando. Tenha um bom sistema de recuperação automática quando as tarefas falharem. Orquestre os recursos de CPU e GPU de alguma forma atômica. E faça uma varredura dos parâmetros do VLM. O que essa configuração nos ajudou a alcançar é bastante…
19:14 simples. No fim de 2014 — desculpem, 2024 — só conseguíamos gerar cerca de 30 bilhões de tokens sintéticos em execuções limitadas no nosso cluster SERM. Nossos requisitos de dados sintéticos aumentaram bastante. Então, no fim do ano passado, conseguimos executar essas enormes tarefas de dados sintéticos que, neste caso, geraram cerca de 7 trilhões de tokens para a web e mais 5 trilhões para matemática e código, para vários clientes nossos. Continuamos fazendo ablações e buscando receitas melhores…
19:45 de dados sintéticos. Estamos trabalhando ativamente nisso, então fiquem de olho. Vamos publicar mais. E acho que a cobertura de domínios é muito importante. Acho que uma coisa de que não falamos hoje é como isso difere entre dados da web, multilíngues, de matemática e código, dados jurídicos etc. A propósito, estamos contratando em várias áreas: infraestrutura de dados, infraestrutura de nuvem, infraestrutura em geral, gerentes de programa etc. Então, falem comigo depois. Agradeço à equipe que trabalhou nisso e a todos por assistirem à minha palestra.
20:28 [música]
Transcrição original
[00:01] [music] We’re doing this. Hey everyone, welcome to my talk. I’m Bogdan. I’m one of the co-founders and the CEO of Theology. Today we’re going to talk about the engineering lessons from scaling synthetic data for trillion token scale pre-training. Um, let’s see. So why do we need synthetic data in the first place? Well, turns out that with the
[00:32] scaling laws, we kind of hit a data wall um you need to put exponentially more compute and exponentially more data to get um models that are getting kind of linearly better and better. So um we’re we’re at this point where pre-training runs are massive. So in order to do the the kind of the ones that actually get to I don’t know the mythos level um capabilities you need a lot of data and a lot of it uh cannot be found on the web. So um internet has limited amount of data um we can supplement it with
[01:03] high quality synthetic data. So what are we going to talk about today? We’re going to talk about um you know how do we do this in the first place? We’re going to talk about a bit about beyond web which is kind of our syntheta data recipe. Um we’re going to talk about the engineering lessons from our prior experience here at Ethology of running trillion tail trillion um token scale synthetic data runs. Um we recently completed one for about 12 trillion tokens. That’s across web math and code. And we’re going to talk about what we learned from running absolutely massive
[01:34] synthetic runs. Um and then we’re going to talk about kind of what’s the why does this matter in the first place. Um awesome. So let’s get started. Um, so the way that we solve synthetic data at theology and maybe let’s start with a with a quick intro about it. We’re a kind of data curation service. Think of us as the oil refinery for your kind of pre-training and mid-training data sets. We work with customers both startups and enterprises that come to us to um kind of help them with their pre-training and
[02:05] mid-training data needs. So in general they have a lot of data. um they want to get to the best data sets possible and we help them identify the the highest quality data points and um once we do that we pass them through our synthetic data recipe the ones that we’re going to talk about today um to get absolutely massive data sets. So um that’s a bit about us uh in terms of beyond web is is our synthetic data recipe. Um there’s kind of many ways to do synthetic data but um kind of the the way that we approach it is um quite different. So here’s a few results from from um kind
[02:36] of how we do this. So uh there’s two plots. Maybe let’s start with the first one. Um on the x-axis we have the model size and billions of parameters. Um 1 billion, 3 billion, 8 billion. And then on the y-axis we have um accuracy. So um we’ve taken kind of a number of data sets like Neotron Synth, Cosmopedia, QA rap, um Red Pajama, and then we’ve trained models at kind of 1B, 3B and 8B scale together with um kind of the the recipe we’ve put together for for uh synthetic data which we call beyond web.
[03:07] Um and what we see is that um kind of our synthetic data recipe um kind of matches and and sometimes even um kind of in this case the the 3B data point matches the 8B data point um for neatron synth. So that means that you can train slightly smaller models for the same performance as you would train larger ones by using synthetic data. So um that’s a bit about kind of the the the quality of of our recipe. Um same thing
[03:37] here when you when you talk about performance. So on the x axis we have um kind of number of tokens in billions and then the y- axis we have uh the the average accuracy. Um and what we show is that we match the the the performance of um kind of the the um Neotron synth and the Cosmopedia ones in about 2.7x and 5.3x respectively uh less tokens. So uh if you want to train a model to the same performance, you can do that um by using less data and and overall less compute.
[04:08] Um so at a high level what what beyond web is is is kind of how we think about our synthetic data recipe. What we do is we do rephrasings. Um so where we we kind of see the rephrase the the synthetic data process by um kind of finding the highest quality data points in a customer’s data set and then we rephrase or restructure this data points in in various ways. Um this is results are actually a bit old. I think the the origin we published this in uh in um I think late summer 25 and at this point we’re we’re much much better than this
[04:39] um and and we’re continuing to improve quite a bit. So how do you get synthetic data right in the in the simplest form you have some sort of target data set again we’re doing rephrasings um or reframings of existing documents. So the idea behind it is that um if you just prompt a model and say hey give me a synthetic data um data point you’re going to just learn the modes of the distribution the data was was origin trained on. So uh the way that we do it as mentioned previously is that we seed it with um some sort of existing documents. So we identify high quality
[05:10] documents in the customer’s um training data sets and then we we pass them through through our pipeline. At the simplest set, we have a a target data set. Imagine this can be text, this can be image text. Um, in the simplest forms, it is just a bunch of prompts that that we prefix to um a number of documents that we’ve identified. You have a bunch of GPUs and then you um kind of use various models to generate synthetic data. Um so in practice, you have some sort of um expectations around how much time this is going to take. But
[05:42] in practice, this is a lot more wavy and and it it really it’s really hard to match the the kind of ideal throughput that you’re trying to get of your um out of your GPUs. So, how do we manage that? Well, well, where did we start? We started where um synthetic data wasn’t integrated in our product was something that we would do in a research setting uh on a cluster that that runs slurm that is away from our core kubernetes-based pipeline. Uh we had this two-track system where kind of the product and the research team would would not use the same type of codebase. This was slow, errorprone, um, limited
[06:13] in velocity and kind of led to underutilizing our GPUs. We have a set number of GPUs like everybody out there. And in general, we want to be able to to maximize the the the use of our GPUs by running this in a in a cohesive way both with training and synthetic data runs. Um, so where do we start? In general, um, we’d like to run everything on on Kubernetes. Um, a lot of our pipeline is either Ray or Spark. Today we’re going to talk about um kind of ray and cube and vlm um those are kind of the core components of our synthetic data library
[06:44] um or data um kind of pipelines. So today what we do is we have an orchestration layer in one kubernetes cluster. We um run spark in another Kubernetes clusters and um we we keep the aster tracker which is our data catalog in the original control cluster where everything um kind of gets coordinated um into um all the data is stored in S3 that’s our storage layer um as long as it speaks kind of S3 compatible APIs we can run it. So in some ways we everything needs to run in Kubernetes because our pipelines get deployed in all sorts of environments.
[07:16] Um it can be AWS, it can be GCP, it can be onrem etc. We want to make sure that that um kind of we can run it in any um Kubernetes environment. And then separately we had this H100 cluster. Um it ran synthetic, it run training, it ran eval kind of a number of things. All of them originally orchestrated by slurm. Um moving data in between these two clusters was manual. So whenever you generated synthetic data in slurm, you had to backfill it into the the asset tracker into our data catalog. So where are we now? So um kind of same setup in some ways where we have the the original
[07:47] cluster um that that does the control. We have the compute cluster that that we run spark jobs and now we have this other H100 compute cluster in in our case we run everything on AWS. We run it on hyper pod. Hyperpod has this product called um EKS on hyper pod. So it’s basically a bunch of H100 clusters on the same spine all of them um orchestrated by uh by Kubernetes. So what we do is we continue to run spark and um ray jobs on demand capacity on demand CPUs and sometimes on demand GPUs um especially for for things that we don’t require H100s we can do that um
[08:18] and then we orchestrate it in a similar way that that we’ve done before where kind of spark runs within its Kubernetes cluster and then ray runs within um the same cluster for um GPUs that are not H100s and anything that we need to do for um H100 nodes we go to the this other Kubernetes cluster and we we kind of have a job scheduler that we’ve built internally that that orchestrates all of these things. Um if we do this then this allows us to to run fast experiments. Imagine that you can run kind of um curate where you run
[08:49] a bunch of spark jobs, you run a bunch of synthetic data, then you go and and launch a training job and then you run an eval job and you can orchestrate all of this together in one workflow which um for our research team is is quite useful and this is puts the the the research flow and the engineering flow in in the same lines in the same infrastructure in the same code in the same path. Okay. So, um we where are we now, right? Like where Oh, look. I have a a oneonone with someone on this fine. Um where where we’re at is um kind of synthetic data is is a core thing to to
[09:21] our workflows. Um we have we run experiments all the time. We we do this crosscluster scheduling. It’s a lot more faster. It’s a lot more reliable and we can run it at scale. So, um we’ve recently done a massive um synthetic data run. Uh let’s talk a bit about the the engineering lessons that that we learned from this right. So um what are the bottlenecks at at trillion token scale? Um well first and foremost um internet scale um for for text data set is is quite limited right on on the web we can find about 30 trillion tokens
[09:52] give or take for um images there’s about 2 12.8 8 billion in in things like dataccom for or for text we usually start from existing highquality data sets like fine web dcmotron um we can we can um kind of put them all together and we get this this large data sets um but at this scale um usually everything gets stored in parquet or some sort of of format you have millions of data partitions um if you’re trying to fetch all of them from s3 at a high rate you might get throttled and then if
[10:22] you especially if you run this on ray um your your ray metadata uh is becomes and how you manage that becomes a bottleneck and that leads to the the worst thing possible which is that you get idle GPUs. So bottleneck um that that we initially seen is that we have um S3 we try to fetch things from our array head. um this has some sort of metadata store. um this is kind of quite slow and and if you do one request that takes 10 milliseconds and and um you’re trying to to do I don’t know millions and millions
[10:54] of them add I don’t know let’s say um if you need to do um kind of the metadata fetches originally those are more expensive um and there’s also a rate limit so if you need to do millions of them you’re going to get rate limited then your workers are going to be quite slow um so we kind of ran the the the back of the anvil of math just to populate the the metadata for um trillions and trillions in tokens. It would take about 9 to 11 days, which is unacceptable, right? You if you’re running this, you’re probably running on millions of dollars in compute. You cannot have them um just waiting for you
[11:25] to fetch metadata for for 11 days. So, the the um way that we’ve went past this is that um instead of of kind of um kind of going to S3, you can actually do um requests that are um batched together. So, instead of doing one at a time, you can batch them all together. S3 supports this through their APIs. And then this way um you can you can do this uh at at a massive scale by kind of increasing the the um the page size of your if your batches to to kind of the limit that
[11:56] that S3 gives you um which is about a thousand um kind of requests in one list and that gets you to about um kind of two hours of API processing time to get your your metadata. So, first lesson, um, make sure that you know how you manage your metadata and make sure that you have, um, kind of thought through just getting the state of your S3 buckets into whatever synthetic data system that you have in order for you to, um, kind of be able to to even start doing this at scale. So, 11 days to two
[12:27] hours. Uh, that’s that’s the first one. Um, awesome. So, the second one is GPU instability. So whenever you’re running um these types of large scale synthetic data runs, of course you’re going to hit some sort of bad GPUs, right? So that means that the machine might go down. Uh GPU might be bad. Something around those lines. Everything that you can expect when you try to run it at scale would happen. So that leads to loss progress that leads to kind of wasted compute, partial outputs, um if you if you only
[12:58] parse through half of the file. And of course at the end of the day you’re going to uh need more cluster time which is always hard to get. Um so the the the way that we do this in in our pipeline is that we have a Spark job that outputs the the the prompts together with the the documents that we need to rephrase that it’s it stitches them together. Um and then we start a rig job that that can actually uses the GPUs, right? Um so the the problem is that there’s some sort of onetoone mapping between input and output. That’s that’s kind of how we we usually structure these types of
[13:30] jobs. Um, in practice, if your partitions are um quite large, what happens is that um you’re going to do a bunch of of of um kind of progress. And then if you if if a refrazing job on one node for one file for one partition takes eight hours and the box goes down in the last five minutes of those eight hours, you’re going to lose a lot of time. So you need to think about um kind of you either have to checkpoint and whenever you do progress within the
[14:02] synthetic data um jobs you need to periodically say okay let me stop and like flash this back into S3 or um you need to have partitions that are small enough that you can tolerate that downtime. So um you need to to think about either your partition size or in general kind of have some sort of checkpointing. Um what we’ve done is is a bit of both where we’ve managed to right size our partition sizes and checkpoint as well when it comes to this things. So um basically whenever um a job fails it gets retrieded but the
[14:33] amount of um kind of time that we lose is it’s minimal and it makes sense for the setup that we have. Um so from multi-day job failures now we have recoverable retries and it it it works it works as as expected. So just to recap resumeum execution some sort of IDM potency where whenever you’re checkpointing you can override the file that you’re checkpointing into and then you need to have some sort of mechanism for for simless recovery um cross infrastructure orchestration. So in in our case the the the cluster where we
[15:04] origin run curation in general our pipeline runs in a centralized location and then customers might have synthetic data um jobs that run in various GPU locations throughout the world right you might it’s going to be hard to get especially for synthetic data where you don’t need necessarily fast networking in between your GPU nodes to get a lot of capacity in one place so what happens then is that you need to be able to orchestrate all of these jobs um in in various clusters so it’s not just one GPU cluster that you’re working with you’re working with um kind of a number of them. Um the problem here is that
[15:35] whenever you have um and you’re trying to to to schedule um these jobs is that you might be able to um kind of schedule your CPU requirements for your ray jobs but not necessarily your um kind of GPU requirements in the GPU pool. So you need to think about kind of being able to schedule in some sort of fashion across these two things. Now um once you have the the next job coming in um you have GPU pull capacity but you don’t have CPU pull capacity right so in general whenever you’re trying to do
[16:06] this this type of cross infra or orchestration you need to think about scheduling and you need to think about um kind of being able to schedule this effectively um and in this case as I mentioned you you you will get to a point where you cannot schedule effectively so what happens then is that um you you kind of need to think about the the ways in which you do this in a in a proper fashion. So some sort of bin packing problem at the at the end of the day. Uh so how did we solve this? Um so same setup as before. Um we have this
[16:37] orchestrator that runs in a different cluster. We have the compute cluster that runs spark and the the ray jobs that mostly need CPU and then we have the the one that has H100s. Um so whenever we schedule um we have dedicated pools for the specific resources that you need in those clusters. So if you have a spark requirements then you spark you might have a a spark pool that that has CPUs and then you dedicate special pools for um kind of the the ray head. So when you think about um some sort of atomic
[17:08] scheduling you need to think about both your CPU and your GPU requirements in order to do this optimally. So in this case whenever we have more CPU um requirements that we need to schedule because we’ve decoupled these two things um and and then we can schedule the the um head and the worker for array um in a in a more atomic fashion then we don’t have the problems as as before um and then everything scales as expected. So cross in front orchestration um you need to think about multiple providers multiple um clouds that you run this in
[17:40] you need to think about scheduling and u make sure that whenever you schedule CPU and GPU resources especially for the same type of job you do that in a way that that makes sense. Um last up is inference optimizations. Um so whenever you run VLM or whenever you run SG lang um you need to think about the the hyperparameters that you use for your jobs right and uh what what we found is that you need to be u quite disciplined about this and you need to be able to to benchmark this and optimize and have a harness that just focuses on the VLM
[18:10] parameters you can get um a lot of gains um in the case in this case about 40% throughput gains just by tweaking the flats for VLM um and SG line right so in our case we we went with VLM Right now we’re actually testing HGLang as well. We do a lot of batch inference. Um which is very much different from from the the normal online one that everybody is used to. Um but whenever you you kind of orchestrate this through VLM, you need to make sure that you have the the right batch size, you have the right speculative decoding um setup, etc. Um
[18:43] if you do kind of a bunch of grid searches over the parameters that you need to optimize, turns out you can get quite a lot of uh of results in terms of throughput. So to recap, um whenever you you’re trying to do things, make sure that um you think about kind of uh the scale that you’re running at. You have a good system for auto recovery whenever jobs go down. You need to orchestrate in some sort of atomic fashion across CPU and GPU resources. Um and you need to make sure that that you kind of sweep over your VLM parameters. So what what this setup helped us achieve is is quite
[19:14] straightforward. Um and in at the end of 2014, sorry, 2024, uh we can only output around 30 billion synthetic tokens in kind of limited runs within our SERM cluster. Uh our requirements for synthetic data went up by by a bunch. And then um kind of end of last year, we were able to to run this massive uh synthetic data jobs that that um generate in this case for web about 7 trillion tokens and then for math and code another five for a bunch of our customers. uh we’re continuing to ablate and and kind of search for better
[19:45] synthetic G recipes. Um we’re actively working towards this. So keep an eye out. We’ll be publishing more. And um I think domain coverage is quite important. I think something that we haven’t talked today is how does this differ in between web, multilingual, math code, uh legal data, etc. By the way, we’re hiring um throughout the board for data infrastructure, cloud infrastructure, normal infrastructure, program managers, etc. So hit me up afterwards. Uh thank you for the team that worked on this and uh thanks everybody for attending my talk.
[20:28] [music]