Núcleo de Ciência da Computação

O que “Fundamentos de Ciência da Computação (Core CS)” Significa na IA Prática

Sistemas modernos de IA (AI) costumam ser apresentados por meio de modelos (models) — regressão linear (linear regression), Redes Neurais ou a Arquitetura Transformer. Na prática, porém, o código do modelo é apenas uma parte de um sistema de IA. O restante é ciência da computação clássica: estruturas de dados (data structures) que tornam operações rápidas, algoritmos (algorithms) que escalam, sistemas que movem dados de forma confiável e métodos numéricos (numerical methods) que mantêm o treinamento estável.

“Fundamentos de Ciência da Computação” em IA se refere aos conceitos de ciência da computação que sustentam sistemas de ponta a ponta para:

  • Treinamento (training) (otimização em larga escala sobre conjuntos de dados massivos)
  • Inferência (inference) (predição ou geração de baixa latência)
  • Recuperação e busca (retrieval and search) (encontrar informações relevantes com eficiência)
  • Confiabilidade em produção (production reliability) (implantação, monitoramento, tratamento de falhas)
  • Pipelines de dados (data pipelines) (coleta, armazenamento, transformação, governança)

Este artigo faz um panorama das ideias mais importantes de ciência da computação — tanto fundamentos teóricos quanto como elas aparecem em stacks reais de IA. Para aprofundamentos, veja artigos relacionados como Algoritmos e Estruturas de Dados, Complexidade, Fundamentos de Sistemas Distribuídos, Computação Numérica, Programação para Aprendizado de Máquina e Busca.

Representações de Dados: o “Modelo” Oculto

Uma grande fração do desempenho em IA vem de como os dados são representados.

Arrays, tensores e layout de memória (memory layout)

A maior parte do cálculo em aprendizado de máquina (machine learning, ML) é álgebra linear densa (dense linear algebra) em tensores (tensors). Duas implicações práticas:

  • Contiguidade importa: operações em arrays contíguos exploram caches (caches) e coalescência na GPU (GPU coalescing) com SIMD/GPU.
  • Passos (strides) importam: uma visão transposta pode ser barata de criar, mas cara de usar repetidamente.

Ideias-chave:

  • Layouts row-major vs column-major
  • Localidade de cache e largura de banda de memória (frequentemente o verdadeiro gargalo)
  • Processamento em lote (batching) para amortizar overhead e melhorar a utilização de hardware

Representações esparsas (sparse representations)

Muitos problemas de IA têm estrutura esparsa: saco de palavras (bag-of-words), arestas de grafos, interações em sistemas de recomendação (recommender systems), padrões de atenção (attention) esparsos. Representações esparsas reduzem memória e computação, mas introduzem overhead e complexidade.

Formatos comuns:

  • CSR/CSC para matrizes esparsas
  • COO para construção fácil
  • Atributos esparsos baseados em hash (hash-based sparse features) (hashing de atributos (feature hashing))

Exemplo: hashing de atributos para atributos categóricos de alta cardinalidade:

def hashed_features(tokens, dim=2**20):
    # Simple hashing trick: map tokens to indices in a fixed vector
    x = [0] * dim
    for t in tokens:
        idx = hash(t) % dim
        x[idx] += 1
    return x

Esse truque clássico de ciência da computação evita manter um dicionário gigantesco, trocando colisões por memória constante.

Grafos, árvores e sequências

Sistemas de IA frequentemente manipulam dados estruturados:

  • Grafos: grafos de conhecimento, redes sociais, grafos de dependência, grafos computacionais (autodiff)
  • Árvores: árvores de decisão, árvores de parsing, árvores de prefixos (trie) para dicionários de tokens
  • Sequências: fluxos de tokens, séries temporais, logs de eventos

Exemplo prático: uma árvore de prefixos acelera a tokenização baseada em prefixos (comum em tokenizadores de subpalavras (subword tokenizers)) e pode dar suporte à decodificação incremental (incremental decoding) eficiente em geração com restrições (constrained generation).

Algoritmos em Todo Lugar: Não Apenas “Treinamento”

Mesmo que seu modelo seja uma rede neural, seu sistema provavelmente depende de algoritmos clássicos.

Ordenação, seleção e top‑k

A seleção top‑k (top‑k) aparece em:

  • decodificação por busca em feixe (beam search)
  • recuperação de vizinhos mais próximos (nearest neighbors)
  • ranqueamento de candidatos em sistemas de recomendação
  • escolha dos próximos tokens de maior probabilidade durante a geração

O top‑k pode ser feito mais rápido do que ordenar a lista inteira. Muitas bibliotecas usam algoritmos de seleção (ou abordagens baseadas em heap) por baixo dos panos.

Hashing e indexação

Tabelas hash (hash maps) são fundamentais para:

  • consulta de vocabulário (token → id)
  • memoização (memoization) e cacheamento (caching)
  • desduplicação (deduplication)
  • repositórios de atributos (feature stores) (indexados por IDs de entidades)

Mas o desempenho depende de:

  • boas funções de hash (hash functions)
  • fatores de carga (load factors) e redimensionamento (resizing)
  • evitar colisões patológicas (collisions)

Programação dinâmica (dynamic programming, DP)

A programação dinâmica é central na “IA clássica” e ainda é relevante:

  • decodificação de Viterbi em modelos ocultos de Markov (Hidden Markov Models, HMMs) / campos aleatórios condicionais (Conditional Random Fields, CRFs)
  • alinhamento de sequências (sequence alignment)
  • certos procedimentos de inferência exata (exact inference) em Modelos Gráficos Probabilísticos (Probabilistic Graphical Models)

Mesmo em cenários neurais, ideias de programação dinâmica aparecem em:

  • alinhamento CTC (Conexão Temporal Classificatória (Connectionist Temporal Classification, CTC)) (fala)
  • avaliação baseada em distância de edição
  • restrições de predição estruturada (structured prediction)

Vizinho mais próximo aproximado (approximate nearest neighbor, ANN)

Sistemas aumentados por recuperação (retrieval-augmented systems) (por exemplo, geração aumentada por recuperação (retrieval-augmented generation, RAG) para modelos de linguagem grandes (large language model, LLM)) dependem de busca rápida de vizinhos mais próximos sobre incorporações (embeddings). O k-vizinhos mais próximos (k-nearest neighbors, kNN) exato costuma ser lento demais em escala, então os sistemas usam índices de vizinho mais próximo aproximado (por exemplo, HNSW, IVF, PQ).

A ideia central de ciência da computação: trocar exatidão por velocidade com tempo de consulta sublinear e memória limitada.

Algoritmos de streaming (streaming algorithms)

Em produção, frequentemente você não consegue armazenar tudo. Algoritmos de streaming fornecem:

  • contagens aproximadas (esboço Count-Min (Count-Min Sketch))
  • amostragem por reservatório (reservoir sampling)
  • estatísticas online (online statistics) (atualizações de média/variância)

Eles aparecem em monitoramento, logging e aprendizado online (online learning).

Complexidade: Escalar, Não Apenas Big‑O

A notação Big‑O (Big‑O) é um ponto de partida, mas workloads de IA expõem restrições adicionais: fatores constantes, largura de banda de memória, overhead de paralelismo e coordenação distribuída.

Complexidade de tempo e espaço na prática de aprendizado de máquina

  • O tempo de treinamento frequentemente escala com (número de tokens) × (FLOPs por token do modelo), onde FLOPs são operações de ponto flutuante (FLOPs).
  • A latência de inferência depende de comprimento da sequência, tamanho do lote e movimentação de memória.
  • Gargalos em pipelines de dados frequentemente são limitados por E/S (I/O-bound), não limitados por computação (compute-bound).

Entender o comportamento assintótico ainda importa:

  • Atenção O(n²) fica cara em comprimentos de contexto longos.
  • Indexação ou ordenação O(n log n) geralmente é ok até que n seja massivo ou repetido com muita frequência.

Para uma intuição mais profunda, veja Complexidade.

Leis práticas de escalonamento: largura de banda e limites de paralelismo

Duas leis clássicas de sistemas são especialmente relevantes:

  • Lei de Amdahl (Amdahl’s law): ganhos com paralelismo são limitados pela fração sequencial.
  • Lei de Gustafson (Gustafson’s law): com problemas maiores, o paralelismo pode continuar efetivo.

Em IA: você pode ter 99% de multiplicações de matrizes (matrix multiplies) paralelizáveis, mas o 1% restante (tokenização, pré-processamento do lado da CPU, sincronização) pode dominar em escala.

Computação Numérica: Onde a Teoria Encontra o Hardware

IA é “apenas matemática”, mas implementada com precisão finita e restrições de hardware. Questões numéricas podem quebrar o treinamento silenciosamente ou produzir saídas instáveis.

Ponto flutuante (floating point), precisão e estabilidade

Conceitos-chave:

  • floats IEEE 754 (FP32, FP16, BF16)
  • overflow/underflow
  • acúmulo de erro de arredondamento
  • condicionamento (conditioning) (sensibilidade das saídas a perturbações na entrada)

Treinamento moderno comumente usa precisão mista (mixed precision) (cálculo FP16/BF16 com acumulação em FP32) para melhorar a vazão (throughput), especialmente em GPUs/TPUs.

Exemplo prático: uma função softmax (softmax) numericamente estável usa o “truque do máximo (max trick)”:

import numpy as np

def softmax_stable(x):
    x = np.asarray(x)
    x_shifted = x - np.max(x)          # prevents exp overflow
    exps = np.exp(x_shifted)
    return exps / np.sum(exps)

Sem subtrair max(x), logits grandes podem causar overflow em exp() e produzir NaNs.

Para mais, veja Computação Numérica.

Diferenciação automática (automatic differentiation, autodiff) e grafos computacionais

Treinar modelos profundos depende de diferenciação automática, que constrói um grafo computacional (computational graph) e aplica a regra da cadeia (chain rule) de forma eficiente (a autodiferenciação em modo reverso (reverse-mode autodiff) é essencialmente o que torna a Retropropagação (Backpropagation) prática).

Ideias centrais de ciência da computação envolvidas:

  • representação e travessia de grafos
  • trade-offs de memória/tempo (checkpointing de ativações (activation checkpointing))
  • otimizações ao estilo de compilador (compiler-style optimizations) (fusão de kernels (kernel fusion), eliminação de subexpressões comuns (common subexpression elimination))

Em modelos grandes, gerenciamento de memória e escalonamento do grafo podem ser tão importantes quanto a matemática.

Modelos de Programação para Aprendizado de Máquina: Correção, Desempenho, Reprodutibilidade

Código de IA é frequentemente escrito em Python, mas as partes críticas de desempenho rodam em kernels otimizados (optimized kernels). Entender o modelo de programação ajuda a evitar armadilhas de “Python lento” e problemas de correção.

Vetorização e processamento em lote

Operações vetorizadas (vectorized) movem loops do Python para kernels otimizados:

# Slow: Python loop
y = []
for i in range(len(x)):
    y.append(x[i] * w + b)

# Fast: vectorized
y = x * w + b

O processamento em lote melhora a vazão ao amortizar overhead e aumentar a utilização paralela, mas pode aumentar a latência — um trade-off importante em produção.

Determinismo e reprodutibilidade

Reprodutibilidade é mais difícil do que “definir uma semente (set a seed)”:

  • kernels de GPU podem ser não determinísticos (nondeterministic) (operações atômicas (atomic ops), reduções paralelas (parallel reductions))
  • treinamento distribuído (distributed training) muda a ordem das operações
  • embaralhamento de dados (data shuffling) e aumento de dados (data augmentation) adicionam aleatoriedade

Boas práticas:

  • registrar versão do dataset + versão do código + configuração (config)
  • registrar sementes e estados de geradores de números aleatórios (RNGs)
  • usar modos determinísticos (deterministic modes) ao depurar (aceitando menor velocidade)

Mais orientação prática está em Programação para Aprendizado de Máquina.

Armadilhas de concorrência (concurrency)

Mesmo serviços de inferência aparentemente “simples” têm questões de concorrência:

  • segurança de thread (thread safety) em tokenizadores
  • filas de processamento em lote de requisições (request batching queues)
  • caches compartilhados (condições de corrida (race conditions))
  • coordenação entre E/S assíncrona (async I/O) e computação CPU/GPU

Ferramentas centrais de ciência da computação: travas (locks), filas (queues), contrapressão (backpressure) e separação cuidadosa de estado mutável (mutable state).

Sistemas de Dados: Armazenamento, Pipelines e Recuperação

Sistemas de IA são tão bons quanto seus pipelines de dados.

Formatos de arquivo e padrões de acesso

Padrões comuns:

  • Formatos colunares (columnar formats) (Parquet/Arrow) para análise e geração de atributos
  • Formatos de registros (record formats) (TFRecord, WebDataset) para leituras sequenciais rápidas durante o treinamento
  • Mapeamento de memória (memory mapping) para arrays grandes somente leitura (incorporações, índices)

O padrão de acesso importa:

  • leituras aleatórias (random reads) podem derrubar a vazão em armazenamento em rede (network storage)
  • streaming sequencial (sequential streaming) permite pré-busca (prefetching) e paralelismo de pipeline (pipeline parallelism)

Cacheamento e memoização

Caches melhoram latência e reduzem custo computacional:

  • cache de tokenização (texto → ids de tokens)
  • cache de incorporação (consulta → vetor)
  • cache de saída (prompt → resposta), quando a política permite

Estratégias clássicas de cache: LRU/LFU, expiração por TTL (time-to-live, TTL), cache com consciência de shard (shard-aware caching) em implantações distribuídas.

Repositórios de atributos e consistência online/offline

Para modelos supervisionados (supervised models), um grande risco em produção é o desalinhamento entre treinamento e serviço (training-serving skew): atributos computados de forma diferente durante o treinamento vs inferência.

As soluções são em grande parte de ciência da computação/projeto de sistemas:

  • definições de atributos compartilhadas
  • transformações versionadas
  • validação forte e rastreamento de linhagem

Sistemas Distribuídos: Treinamento e Serving em Escala

Quando modelos ou conjuntos de dados excedem uma única máquina, conceitos de sistemas distribuídos tornam-se essenciais.

Estratégias de paralelismo no treinamento

Abordagens comuns:

  • Paralelismo de dados (data parallelism): replicar o modelo, dividir os dados; agregar gradientes (frequentemente via operação all-reduce (all-reduce)).
  • Paralelismo de modelo (model parallelism): dividir o modelo entre dispositivos (paralelismo tensorial (tensor parallelism) / paralelismo de pipeline (pipeline parallelism)).
  • Paralelismo híbrido (hybrid parallelism): combinar ambos para modelos muito grandes.

Cada abordagem introduz trade-offs em:

  • volume de comunicação
  • custo de sincronização
  • tratamento de falhas e criação de pontos de verificação (checkpointing)
  • complexidade de engenharia

Tolerância a falhas e pontos de verificação

Treinamentos longos precisam tolerar:

  • instâncias preemptadas (preempted instances)
  • falhas transitórias de rede (transient network failures)
  • quedas de nós (node crashes)

Pontos de verificação introduzem seus próprios desafios de ciência da computação:

  • snapshots consistentes (consistent snapshots) (modelo + otimizador (optimizer) + RNG + estado do carregador de dados (dataloader))
  • gravações atômicas (atomic writes) e prevenção de corrupção
  • checkpoints incrementais (incremental checkpoints) para reduzir E/S

Consistência, coordenação e desempenho

Serving distribuído adiciona questões como:

  • balanceamento de carga (load balancing) e latência de cauda (tail latency)
  • coerência de cache (cache coherence) (ou incoerência deliberada)
  • implantações graduais (rolling deploys) e desalinhamento de versão (version skew)
  • limitação de taxa (rate limiting) e contrapressão

Para um tratamento dedicado, veja Fundamentos de Sistemas Distribuídos.

Busca: Da IA Clássica à Decodificação e Recuperação Modernas

Busca é um pilar central de ciência da computação que atravessa IA simbólica (symbolic AI) e aprendizado de máquina moderno.

Busca em grafos no planejamento e na tomada de decisão

Algoritmos clássicos (BFS, DFS, A*) dão suporte a:

  • planejamento (planning) em ambientes discretos
  • busca de caminhos e roteamento
  • certas formas de raciocínio estruturado

Essas ideias também aparecem em:

  • busca em síntese de programas (program synthesis search)
  • decodificação baseada em restrições (constraint-based decoding)
  • busca em árvore (tree search) para tomada de decisão (por exemplo, busca em árvore de Monte Carlo (Monte Carlo Tree Search, MCTS) em agentes de jogos)

Busca na inferência de modelos de linguagem grandes

A decodificação de modelos de linguagem grandes é busca sobre sequências de tokens:

  • decodificação gulosa (greedy decoding) (rápida, frequentemente de menor qualidade)
  • busca em feixe (mantém múltiplas hipóteses)
  • estratégias de amostragem (sampling strategies) (temperatura (temperature), top‑p (top‑p))

O “modelo” fornece probabilidades; a busca decide como explorar o espaço.

Mais em Busca.

Engenharia de Confiabilidade para Sistemas de IA

Um sistema de IA é software que precisa ser correto, seguro, observável (observable) e sustentável para manutenção.

Testes além da acurácia

Você ainda precisa de testes unitários e de integração (unit and integration tests):

  • correção do pré-processamento
  • invariantes de forma/tipo de dado (shape/dtype invariants)
  • compatibilidade de serialização (serialization compatibility)
  • verificações de assinatura do modelo (model signature) (entradas/saídas)

Além disso, testes específicos de IA ajudam a capturar regressões:

  • conjuntos de referência (golden sets) para avaliação
  • testes metamórficos (metamorphic tests) (invariantes sob perturbações inofensivas)
  • testes de desempenho (performance tests) (latência, vazão, memória)

Observabilidade e ciclos de realimentação

IA em produção exige:

  • métricas (metrics) (latência, taxas de erro, saturação)
  • monitoramento de qualidade do modelo (deriva (drift), calibração (calibration), desempenho por recorte (slice performance))
  • registro de dados (data logging) com restrições de privacidade/segurança (privacy/security constraints)

Ciclos de realimentação podem causar comportamento não intencional (por exemplo, recomendações reforçando popularidade). Isso se conecta a ideias de Inferência Causal (Causal Inference) e avaliação responsável.

Considerações de segurança e robustez

Tópicos centrais de segurança em ciência da computação importam:

  • validação de entrada (input validation) (prevenir crashes e esgotamento de recursos (resource exhaustion))
  • isolamento em sandbox (sandboxing) de entradas/ferramentas não confiáveis
  • segurança de dependências (dependency security) e risco de cadeia de suprimentos (supply-chain risk)

Para aplicações com modelos de linguagem grandes, “injeção de prompt (prompt injection)” e uso indevido de ferramentas (tool misuse) são manifestações mais novas de problemas antigos de segurança: entradas não confiáveis controlando a execução.

Juntando Tudo: Um Exemplo Concreto de Sistema

Considere um sistema de perguntas e respostas (question answering, QA) aumentado por recuperação:

  1. Ingerir documentos (ingest documents)
    • Fazer parsing e fragmentar (chunk) o texto
    • Armazenar fragmentos em um armazenamento de objetos (object store) ou banco de dados
  2. Construir um índice de incorporações (embedding index)
    • Calcular incorporações vetoriais (vector embeddings) em lotes (GPU)
    • Construir um índice de vizinho mais próximo aproximado (por exemplo, HNSW)
  3. Atender consultas (serve queries)
    • Tokenizar a consulta
    • Gerar a incorporação da consulta
    • Recuperar os fragmentos top‑k do índice de vizinho mais próximo aproximado
    • Alimentar o texto recuperado + a consulta em um modelo de linguagem grande para geração

Onde os Fundamentos de Ciência da Computação aparecem:

  • Estruturas de dados: árvores de prefixos (tokenizador), índices vetoriais, heaps para top‑k
  • Algoritmos: busca de vizinho mais próximo aproximado, desduplicação, cacheamento
  • Complexidade: recuperação e comprimento de contexto determinam latência e custo
  • Computação numérica: softmax estável, inferência em precisão mista
  • Sistemas distribuídos: fragmentação (sharding) de índices, pools de workers (worker pools) de GPU, tentativas de novo (retries)
  • Confiabilidade: monitorar taxas de acerto da recuperação (retrieval hit rates), caminhos de fallback (fallback paths) quando o índice estiver degradado

Mesmo que a “parte de IA” seja incorporações + um modelo de linguagem grande, a maioria das falhas e estouros de custo vem da ciência da computação ao redor.

Como Usar Fundamentos de Ciência da Computação como Praticante de IA

Uma forma prática de construir boa intuição é mapear sintomas para causas de ciência da computação:

  • Treinamento está lento → verificar E/S, processamento em lote, vetorização, complexidade algorítmica
  • Inferência está cara → verificar cacheamento, quantização (quantization), estratégia de lote, movimentação de memória
  • Resultados estão instáveis → verificar estabilidade numérica, precisão, não determinismo, deriva de dados
  • Escalar quebra → verificar coordenação distribuída, pontos de verificação, estratégia de fragmentação

Fundamentos de Ciência da Computação não substituem conhecimento de aprendizado de máquina; eles viabilizam que o aprendizado de máquina funcione com confiabilidade em escala real. Combine-os com Introdução à Matemática, Teoria do Aprendizado e entendimento específico do modelo para ir de “um notebook que treina” para “um sistema que funciona.”