---
title: "Machine Learning com Zig — É Possível?"
url: "https://ziglang.com.br/artigos/machine-learning-com-zig-%C3%A9-poss%C3%ADvel/"
markdown_url: "https://ziglang.com.br/artigos/machine-learning-com-zig-%C3%A9-poss%C3%ADvel.MD"
description: "Explorando Machine Learning com Zig. Redes neurais, álgebra linear, SIMD para ML, inferência de modelos e integração com ONNX. Análise completa."
date: "2026-02-21"
author: "Zig Brasil"
---

# Machine Learning com Zig — É Possível?

Explorando Machine Learning com Zig. Redes neurais, álgebra linear, SIMD para ML, inferência de modelos e integração com ONNX. Análise completa.


# Machine Learning com Zig — É Possível?

Python domina o mundo do Machine Learning, mas a inferência (execução de modelos treinados) é essencialmente álgebra linear — multiplicação de matrizes, ativações e operações vetoriais. Estas operações são ideais para linguagens de baixo nível como Zig, que oferece SIMD nativo, controle de memória explícito e compilação cruzada. Zig não vai substituir Python para treinamento, mas pode ser excelente para inferência de alta performance.

## Álgebra Linear em Zig

### Multiplicação de Matrizes

A operação fundamental de redes neurais:

```zig
const std = @import("std");

const Matriz = struct {
    dados: []f32,
    linhas: usize,
    colunas: usize,
    allocator: std.mem.Allocator,

    pub fn init(allocator: std.mem.Allocator, linhas: usize, colunas: usize) !Matriz {
        return .{
            .dados = try allocator.alloc(f32, linhas * colunas),
            .linhas = linhas,
            .colunas = colunas,
            .allocator = allocator,
        };
    }

    pub fn deinit(self: Matriz) void {
        self.allocator.free(self.dados);
    }

    pub fn get(self: Matriz, i: usize, j: usize) f32 {
        return self.dados[i * self.colunas + j];
    }

    pub fn set(self: *Matriz, i: usize, j: usize, val: f32) void {
        self.dados[i * self.colunas + j] = val;
    }

    /// Multiplicação C = A * B com SIMD
    pub fn multiplicar(a: Matriz, b: Matriz, c: *Matriz) void {
        std.debug.assert(a.colunas == b.linhas);
        std.debug.assert(c.linhas == a.linhas and c.colunas == b.colunas);

        const vec_len = 8;

        for (0..a.linhas) |i| {
            for (0..b.colunas) |j| {
                var soma_vec: @Vector(vec_len, f32) = @splat(0.0);
                var k: usize = 0;

                while (k + vec_len <= a.colunas) : (k += vec_len) {
                    const a_vec: @Vector(vec_len, f32) = a.dados[i * a.colunas + k ..][0..vec_len].*;

                    // Coletar coluna j de B (stride access)
                    var b_vec: @Vector(vec_len, f32) = undefined;
                    inline for (0..vec_len) |v| {
                        b_vec[v] = b.dados[(k + v) * b.colunas + j];
                    }

                    soma_vec += a_vec * b_vec;
                }

                var soma = @reduce(.Add, soma_vec);
                while (k < a.colunas) : (k += 1) {
                    soma += a.get(i, k) * b.get(k, j);
                }
                c.set(i, j, soma);
            }
        }
    }
};
```

### Funções de Ativação

```zig
/// Funções de ativação vetorizadas
fn relu(dados: []f32) void {
    const vec_len = 8;
    const zero: @Vector(vec_len, f32) = @splat(0.0);

    var i: usize = 0;
    while (i + vec_len <= dados.len) : (i += vec_len) {
        const v: @Vector(vec_len, f32) = dados[i..][0..vec_len].*;
        dados[i..][0..vec_len].* = @max(v, zero);
    }
    while (i < dados.len) : (i += 1) {
        dados[i] = @max(dados[i], 0);
    }
}

fn sigmoid(dados: []f32) void {
    for (dados) |*v| {
        v.* = 1.0 / (1.0 + @exp(-v.*));
    }
}

fn softmax(dados: []f32) void {
    // Encontrar max para estabilidade numérica
    var max_val: f32 = dados[0];
    for (dados[1..]) |v| max_val = @max(max_val, v);

    var soma: f32 = 0;
    for (dados) |*v| {
        v.* = @exp(v.* - max_val);
        soma += v.*;
    }
    for (dados) |*v| v.* /= soma;
}
```

## Rede Neural Simples

```zig
const CamadaDensa = struct {
    pesos: Matriz,
    bias: []f32,
    saida: []f32,
    ativacao: Ativacao,
    allocator: std.mem.Allocator,

    const Ativacao = enum { relu, sigmoid, softmax, nenhuma };

    pub fn init(
        allocator: std.mem.Allocator,
        entrada: usize,
        saida_dim: usize,
        ativacao: Ativacao,
    ) !CamadaDensa {
        return .{
            .pesos = try Matriz.init(allocator, entrada, saida_dim),
            .bias = try allocator.alloc(f32, saida_dim),
            .saida = try allocator.alloc(f32, saida_dim),
            .ativacao = ativacao,
            .allocator = allocator,
        };
    }

    pub fn deinit(self: CamadaDensa) void {
        self.pesos.deinit();
        self.allocator.free(self.bias);
        self.allocator.free(self.saida);
    }

    pub fn forward(self: *CamadaDensa, entrada: []const f32) []f32 {
        // saida = entrada * pesos + bias
        for (0..self.saida.len) |j| {
            var soma: f32 = self.bias[j];
            for (0..entrada.len) |i| {
                soma += entrada[i] * self.pesos.get(i, j);
            }
            self.saida[j] = soma;
        }

        // Aplicar ativação
        switch (self.ativacao) {
            .relu => relu(self.saida),
            .sigmoid => sigmoid(self.saida),
            .softmax => softmax(self.saida),
            .nenhuma => {},
        }

        return self.saida;
    }
};
```

## Inferência de Modelos ONNX

Zig pode carregar e executar modelos treinados em Python via formato ONNX usando interop com C:

```zig
const c = @cImport({
    @cInclude("onnxruntime_c_api.h");
});

const ModeloOnnx = struct {
    env: *c.OrtEnv,
    session: *c.OrtSession,

    pub fn carregar(caminho: [*:0]const u8) !ModeloOnnx {
        var env: *c.OrtEnv = undefined;
        var session: *c.OrtSession = undefined;

        const api = c.OrtGetApiBase().*.GetApi(c.ORT_API_VERSION);

        _ = api.*.CreateEnv(c.ORT_LOGGING_LEVEL_WARNING, "zig-ml", &env);

        const options = blk: {
            var opts: *c.OrtSessionOptions = undefined;
            _ = api.*.CreateSessionOptions(&opts);
            break :blk opts;
        };

        _ = api.*.CreateSession(env, caminho, options, &session);

        return .{ .env = env, .session = session };
    }
};
```

## Quando Usar Zig para ML

### Zig Brilha Em

- **Inferência em edge/embedded**: Dispositivos com pouca memória
- **Inferência de baixa latência**: Sistemas de tempo real
- **Pré/pós-processamento**: Preparar dados para modelos
- **Modelos customizados**: Implementações especializadas
- **WASM ML**: Modelos rodando no navegador

### Python Continua Melhor Para

- Treinamento de modelos
- Experimentação e prototipagem
- Ecossistema de bibliotecas (PyTorch, TensorFlow)
- Visualização de dados

## Conclusão

Machine Learning com Zig não é apenas possível — é uma opção excelente para cenários específicos. A combinação de SIMD nativo, controle de memória e compilação cruzada torna Zig ideal para inferência de alta performance, especialmente em edge computing e sistemas embarcados.

Se você trabalha com ML, vale conhecer também o ecossistema <a href="https://python.dev.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'python.dev.br' })">Python</a>, que continua sendo a referência para treinamento de modelos, e explorar como <a href="https://rustlang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust</a> vem construindo seu próprio ecossistema de ML com crates como candle e burn.

## Conteúdo Relacionado

- [SIMD e Vetorização em Zig](/tutoriais/zig-performance/artigo-3-simd-vetorizacao/) — SIMD para ML
- [Zig em Sistemas Embarcados](/cases/case-zig-embedded-industria/) — ML no edge
- [WebAssembly com Zig](/artigos/zig-webassembly-2026/) — ML no navegador
- [Otimização de Performance](/tutoriais/zig-performance/) — Série de performance
- [Interoperabilidade Zig-C](/tutoriais/zig-c-interoperabilidade/) — Integrar libs C
