Машинное обучение на Rust: современные библиотеки и инструменты
Язык Rust, известный своей производительностью и безопасностью памяти, активно входит в сферу машинного обучения (ML). Хотя экосистема ML на Rust моложе, чем на Python, она уже предлагает зрелые решения для построения, обучения и развертывания моделей. В этой статье мы рассмотрим ключевые библиотеки, которые позволяют решать задачи машинного обучения на Rust, и приведем практические примеры.
Почему Rust для машинного обучения?
Rust предоставляет уникальные преимущества:
- Производительность: Компилируемый код на Rust сравним по скорости с C/C++, что критично для обучения больших моделей.
- Безопасность: Система владения (ownership) и заимствования (borrowing) исключает целые классы ошибок (data races, null pointers).
- Кроссплатформенность: Легко компилируется под WebAssembly, мобильные устройства и встраиваемые системы.
- Интеграция с Python: Можно писать высокопроизводительные модули на Rust и вызывать их из Python через PyO3.
Основные библиотеки для ML на Rust
1. Linfa — швейцарский нож ML
Linfa — это аналог scikit-learn для Rust. Она предоставляет унифицированный интерфейс для стандартных алгоритмов. Поддерживает:
- Линейную и логистическую регрессию
- Метод опорных векторов (SVM)
- Кластеризацию (K-Means, DBSCAN)
- Методы понижения размерности (PCA)
- Деревья решений и случайный лес
Пример линейной регрессии с Linfa:
use linfa::prelude::*;
use linfa_linear::LinearRegression;
use ndarray::Array2;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Создаем синтетические данные: 100 точек, 3 признака
let x = Array2::random((100, 3), rand::distributions::Uniform::new(-1.0, 1.0));
let true_weights = arr2(&[[2.0], [-1.0], [0.5]]);
let y = x.dot(&true_weights) + 0.1; // добавляем шум
let dataset = Dataset::new(x, y);
// Обучаем модель
let model = LinearRegression::default().fit(&dataset)?;
// Коэффициенты модели
println!("Веса: {:?}", model.params());
// Предсказание
let predicted = model.predict(&dataset);
println!("MSE: {:?}", predicted.mean_squared_error(&dataset)?);
Ok(())
}
2. Burn — современный фреймворк для глубокого обучения
Burn — это гибкий фреймворк для нейронных сетей, написанный полностью на Rust. Его особенности:
- Поддержка GPU (CUDA, Vulkan, Metal, WebGPU)
- Автоматическое дифференцирование (autograd)
- Гибкая система бэкендов (torch, ndarray, wgpu)
- Динамические графы вычислений
- Экспорт в ONNX
Пример простой нейронной сети на Burn:
use burn::tensor::{Tensor, backend::Backend};
use burn::nn::{Linear, Relu, Sequential};
// Определяем архитектуру сети
struct MyModel<B: Backend> {
linear1: Linear<B>,
linear2: Linear<B>,
activation: Relu,
}
impl<B: Backend> MyModel<B> {
fn new(device: &B::Device) -> Self {
Self {
linear1: Linear::new(784, 256, device),
linear2: Linear::new(256, 10, device),
activation: Relu::new(),
}
}
fn forward(&self, input: Tensor<B, 2>) -> Tensor<B, 2> {
let x = self.linear1.forward(input);
let x = self.activation.forward(x);
self.linear2.forward(x)
}
}
fn main() {
// Используем бэкенд на CPU (ndarray)
type MyBackend = burn::backend::NdArray;
let device = Default::default();
let model = MyModel::<MyBackend>::new(&device);
let input = Tensor::<MyBackend, 2>::random([1, 784], burn::tensor::Distribution::Normal(0.0, 1.0), &device);
let output = model.forward(input);
println!("Output shape: {:?}", output.shape());
}
3. Candle — минималистичный ML от Hugging Face
Candle — легковесный фреймворк от создателей Hugging Face. Идеален для: инференса моделей, edge-устройств и быстрых экспериментов.