candle para Rust: o framework ML minimalista da Hugging Face
candle é um framework moderno para machine learning, escrito em Rust e desenvolvido pela equipe da Hugging Face. Diferente de soluções pesadas como PyTorch ou TensorFlow, o candle foca em performance, segurança de memória e consumo mínimo de recursos. Ele permite executar modelos de redes neurais em CPU e GPU (via CUDA e Vulkan) sem a necessidade de instalar runtimes enormes.
Por que usar o candle? Primeiro, ele é ideal para sistemas embarcados, WebAssembly (WASM) e dispositivos de borda (edge), onde o tamanho do binário e a velocidade de carregamento são cruciais. Segundo, o Rust garante segurança de threads e ausência de garbage collector, proporcionando performance previsível para inferência. Terceiro, o candle suporta carregamento de modelos dos formatos PyTorch (safetensors, bin) e do Hugging Face Hub, tornando-o uma excelente escolha para produção.
No momento em que este artigo foi escrito, o candle está em desenvolvimento ativo: suporta transformers (BERT, GPT, LLaMA, Whisper), redes convolucionais (ResNet, ViT) e até modelos generativos (Stable Diffusion). Neste guia, vamos abordar a instalação, os métodos principais e criar um exemplo completo de classificação de texto.
Instalação
candle é uma biblioteca Rust, então a instalação é feita via Cargo. Adicione a dependência no Cargo.toml:
[dependencies]
candle-core = "0.7"
candle-nn = "0.7"
candle-transformers = "0.7"
tokenizers = "0.21" # para trabalhar com tokenizadores
anyhow = "1.0" # para tratamento de erros
Se você precisar de suporte CUDA, use a flag --features cuda:
cargo add candle-core --features cuda
cargo add candle-nn --features cuda
cargo add candle-transformers --features cuda
Para trabalhar com WebAssembly (WASM), adicione --features wasm.
Início rápido: exemplo mínimo funcional
Vamos criar um tensor e realizar uma operação simples — multiplicação de matrizes:
use candle_core::{Device, Tensor};
fn main() -> Result<(), Box> {
// Criando tensores na CPU
let a = Tensor::new(&[[1.0f32, 2.0], [3.0, 4.0]], &Device::Cpu)?;
let b = Tensor::new(&[[5.0f32, 6.0], [7.0, 8.0]], &Device::Cpu)?;
// Multiplicação de matrizes
let c = a.matmul(&b)?;
println!("Resultado: {:?}", c.to_vec2::()?);
Ok(())
}
Este código exibirá:
Resultado: [[19.0, 22.0], [43.0, 50.0]]
Observe: todas as operações retornam Result, por isso usamos ? para tratar erros.
Métodos e funções principais
Vamos explorar 10 métodos essenciais do candle-core e candle-nn que você usará em 90% dos projetos.
1. Tensor::new — criação de tensor
Assinatura: pub fn new
Descrição: Cria um tensor a partir de um vetor plano de números de ponto flutuante. A forma é definida via Shape (exemplo: Shape::from((2, 3))).
use candle_core::{Device, Tensor, Shape};
fn main() -> anyhow::Result<()> {
// Criando um tensor 2x3 a partir de um vetor
let t = Tensor::new(&[1.0, 2.0, 3.0, 4.0, 5.0, 6.0], &Device::Cpu)?;
// Alterando a forma
let t_reshaped = t.reshape(&Shape::from((2, 3)))?;
println!("{:?}", t_reshaped.to_vec2::()?);
Ok(())
}
2. Tensor::matmul — multiplicação de matrizes
Assinatura: pub fn matmul(&self, other: &Tensor) -> Result<Tensor>
Descrição: Realiza a multiplicação matricial de dois tensores. Suporta broadcasting para batches.
use candle_core::{D