Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym artykule pokazano, jak osadzać i uruchamiać małe modele Open Neural Network Exchange (ONNX) wewnątrz modułów webAssembly w celu wykonywania wnioskowania wewnątrz pasmowego w ramach wykresów przepływu danych operacji usługi Azure IoT. Użyj tego podejścia do wzbogacania i klasyfikacji o małych opóźnieniach bezpośrednio na danych przesyłanych strumieniowo bez wywoływania zewnętrznych usług przewidywania.
Ważne
Obecnie wykresy przepływu danych obsługują tylko punkty końcowe MQTT (Message Queuing Telemetry Transport), Kafka i OpenTelemetry. Inne typy punktów końcowych, takie jak Data Lake, Microsoft Fabric OneLake, Azure Data Explorer i Local Storage, nie są obsługiwane. Aby uzyskać więcej informacji, zobacz Znane problemy.
Dlaczego warto używać interferencji ONNX w pasmie
Za pomocą wykresów przepływu danych operacji usługi Azure IoT można osadzać małe wnioskowanie modelu ONNX bezpośrednio w potoku zamiast wywoływać zewnętrzną usługę przewidywania. Takie podejście oferuje kilka praktycznych zalet:
- Małe opóźnienie: wykonaj wzbogacanie lub klasyfikację w czasie rzeczywistym w tej samej ścieżce operatora, w której docierają dane. Każdy komunikat powoduje tylko lokalne wnioskowanie CPU, unikając przesyłania danych w sieci.
- Kompaktowy rozmiar: docelowe modele kompaktowe, takie jak modele klasy MobileNet. Ta funkcja nie dotyczy dużych modeli transformatorów, przyspieszania procesora GPU/TPU ani częstych wdrożeń modeli A/B.
-
Zoptymalizowane pod kątem określonych przypadków użycia:
- Zgodne z wieloźródłowym przetwarzaniem strumieniowym, gdzie funkcje są już zlokalizowane w grafie
- Zakładane na bazie semantyki czasu zdarzeń, wnioskowanie wykorzystuje te same znaczniki czasu jak inne operatory
- Zachowany dostatecznie mały rozmiar, aby osadzić go z modułem, nie przekraczając praktycznych ograniczeń rozmiaru i pamięci WASM.
- Proste aktualizacje: wprowadzenie nowego modułu z osadzonym modelem WASM, a następnie zaktualizowanie odwołania do definicji grafu. Nie trzeba mieć oddzielnego rejestru modelu ani zmiany zewnętrznego punktu końcowego.
-
Ograniczenia sprzętowe: zaplecze ONNX działa na procesorze przez interfejs systemowy WebAssembly (WASI).
wasi-nnBrak docelowych jednostek GPU/TPU; uruchamiane są tylko obsługiwane operatory ONNX. - Skalowanie w poziomie: wnioskowanie skaluje się w miarę skalowania wykresu przepływu danych. Gdy środowisko uruchomieniowe dodaje więcej pracowników do zwiększenia przepustowości, każdy z nich ładuje osadzony model i bierze udział w procesie równoważenia obciążenia.
Kiedy należy używać wnioskowania ONNX w pasmie
Jeśli masz następujące wymagania, użyj wnioskowania w pasmie:
- Polityka niskiego opóźnienia wymaga wzbogacania lub klasyfikowania komunikatów w czasie ich pobierania.
- Małe i wydajne modele, takie jak modele klasy MobileNet lub podobne kompaktowe modele
- Wnioskowanie, które musi być zgodne z przetwarzaniem czasu zdarzenia i tymi samymi znacznikami czasu co inne operatory
- Proste aktualizacje dzięki wysłaniu nowej wersji modułu ze zaktualizowanym modelem
Unikaj wnioskowania w pasmie, jeśli masz następujące wymagania:
- Duże modele przekształcania, przyspieszanie procesora GPU/TPU lub zaawansowane wdrożenia A/B
- Modele, które wymagają wielu danych wejściowych w postaci tensorów, buforowania par klucz-wartość lub korzystania z nieobsługiwanych operatorów ONNX
Uwaga / Notatka
Chcesz zachować małe moduły i osadzone modele. Duże modele i obciążenia z dużą ilością pamięci nie są obsługiwane. Użyj kompaktowych architektur i małych rozmiarów wejściowych, takich jak 224×224 do klasyfikacji obrazów.
Wymagania wstępne
Przed rozpoczęciem upewnij się, że masz:
- Wdrożenie operacji usługi Azure IoT z funkcją grafów przepływu danych.
- Dostęp do rejestru kontenerów, takiego jak Usługa Azure Container Registry.
- Środowisko programistyczne skonfigurowane na potrzeby tworzenia modułów zestawu WebAssembly.
Aby uzyskać szczegółowe instrukcje dotyczące konfiguracji, zobacz Develop WebAssembly modules (Tworzenie modułów zestawu WebAssembly).
Wzorzec architektury
Typowy wzorzec wnioskowania ONNX w grafach przepływu danych obejmuje:
-
Przetwarzanie wstępne danych: przekształć nieprzetworzone dane wejściowe, aby były zgodne z oczekiwanym formatem modelu. W przypadku modeli obrazów ten proces zwykle obejmuje:
- Dekodowanie bajtów obrazu.
- Zmiana rozmiaru na wymiar docelowy (na przykład 224×224).
- Konwertowanie przestrzeni kolorów (na przykład RGB na BGR).
- Normalizacja wartości pikseli do oczekiwanego zakresu (od 0 do 1 lub -1 do 1).
- Rozmieszczanie danych w poprawnym układzie tensorowym: NCHW (partia, kanały, wysokość, szerokość) lub NHWC (partia, wysokość, szerokość, kanały).
-
Uruchamianie wnioskowania: przekonwertuj wstępnie przetworzone dane na tensory przy użyciu interfejsu
wasi-nn, załaduj osadzony model ONNX za pomocą zaplecza procesora CPU, ustaw tensory wejściowe w kontekście wykonywania, wywołaj przekazywanie do przodu modelu i pobierz tensory wyjściowe zawierające nieprzetworzone przewidywania. -
Dane wyjściowe przetwarzania końcowego: przekształć nieprzetworzone dane wyjściowe modelu w znaczące wyniki. Typowe operacje:
- Zastosuj softmax, aby wygenerować prawdopodobieństwa klasyfikacji.
- Wybierz przewidywania najwyższego poziomu K.
- Zastosuj próg ufności, aby filtrować wyniki o niskiej pewności.
- Mapuj indeksy przewidywania na etykiety czytelne dla człowieka.
- Formatuj wyniki na potrzeby dalszego przetwarzania.
W przykładach IoT dla operatorów Rust WASM można znaleźć dwa przykłady, które są zgodne z tym wzorcem:
- Przykład przekształcania danych "format": dekoduje i zmienia rozmiar obrazów na RGB24 224×224.
- Przykład "migawka" przetwarzania obrazów/wideo: osadza model MobileNet v2 ONNX, przeprowadza wnioskowanie na procesorze i oblicza softmax.
Konfigurowanie definicji grafu
Aby włączyć wnioskowanie ONNX na wykresie przepływu danych, należy skonfigurować zarówno strukturę grafu, jak i parametry modułu. Definicja grafu określa przepływ potoku, a konfiguracje modułów umożliwiają dostosowanie środowiska uruchomieniowego wstępnego przetwarzania i zachowania wnioskowania.
Włącz obsługę WASI-NN
Aby włączyć obsługę interfejsu sieci neuronowej WebAssembly, dodaj wasi-nn funkcję do definicji grafu.
moduleRequirements:
apiVersion: "1.1.0"
runtimeVersion: "1.1.0"
features:
- name: "wasi-nn"
Definiowanie operacji i przepływu danych
Skonfiguruj operacje, które tworzą potok wnioskowania. W tym przykładzie przedstawiono typowy przepływ pracy klasyfikacji obrazów:
operations:
- operationType: "source"
name: "camera-input"
- operationType: "map"
name: "module-format/map"
module: "format:1.0.0"
- operationType: "map"
name: "module-snapshot/map"
module: "snapshot:1.0.0"
- operationType: "sink"
name: "results-output"
connections:
- from: { name: "camera-input" }
to: { name: "module-format/map" }
- from: { name: "module-format/map" }
to: { name: "module-snapshot/map" }
- from: { name: "module-snapshot/map" }
to: { name: "results-output" }
Ta konfiguracja tworzy potok, w którym:
-
camera-inputodbiera nieprzetworzone dane obrazu ze źródła -
module-format/mapwstępnie przetwarza obrazy (dekoduj, zmienia rozmiar, konwersję formatu) -
module-snapshot/mapuruchamia wnioskowanie i postprocesowanie ONNX -
results-outputprzesyła wyniki klasyfikacji do odbiornika
Konfigurowanie parametrów modułu
Zdefiniuj parametry środowiska uruchomieniowego, aby dostosować zachowanie modułu bez ponownego kompilowania. Te parametry są przekazywane do modułów WASM podczas inicjowania:
moduleConfigurations:
- name: module-format/map
parameters:
width:
name: width
description: "Target width for image resize (default: 224)"
required: false
height:
name: height
description: "Target height for image resize (default: 224)"
required: false
pixelFormat:
name: pixel_format
description: "Output pixel format (rgb24, bgr24, grayscale)"
required: false
- name: module-snapshot/map
parameters:
executionTarget:
name: execution_target
description: "Inference execution target (cpu, auto)"
required: false
labelMap:
name: label_map
description: "Label mapping strategy (embedded, imagenet, custom)"
required: false
scoreThreshold:
name: score_threshold
description: "Minimum confidence score to include in results (0.0-1.0)"
required: false
topK:
name: top_k
description: "Maximum number of predictions to return (default: 5)"
required: false
Operator init może odczytywać te wartości za pomocą interfejsu konfiguracji modułu. Aby uzyskać szczegółowe informacje, zobacz Parametry konfiguracji modułu.
Pakowanie modelu
Osadzanie modeli ONNX bezpośrednio w składniku WASM zapewnia atomowe wdrażanie i zgodność wersji. Takie podejście upraszcza dystrybucję i usuwa zależności środowiska uruchomieniowego od zewnętrznych plików modelu lub rejestrów.
Wskazówka
Osadzanie pozwala zachować wersję modelu i logiki operatora. Aby zaktualizować model, opublikuj nową wersję modułu i zaktualizuj definicję grafu, aby się do niego odwoływać. Takie podejście eliminuje dryf modelu i zapewnia powtarzalne wdrożenia.
Wytyczne dotyczące przygotowywania modelu
Przed osadzeniem modelu upewnij się, że spełnia ona wymagania dotyczące wdrożenia WASM:
- Zachowaj modele poniżej 50 MB na potrzeby praktycznych czasów ładowania WASM i ograniczeń pamięci.
- Sprawdź, czy model akceptuje pojedynczy tensor wejściowy w typowym formacie (float32 lub uint8).
- Sprawdź, czy zaplecze środowiska uruchomieniowego WASM ONNX obsługuje każdego operatora używanego przez model.
- Użyj narzędzi optymalizacji ONNX, aby zmniejszyć rozmiar modelu i zwiększyć szybkość wnioskowania.
Osadzanie przepływu pracy
Wykonaj następujące kroki, aby osadzić model i skojarzone zasoby:
-
Organizowanie zasobów modelu: umieść
.onnxplik modelu i opcjonalnielabels.txtw drzewie źródłowym. Użyj dedykowanej struktury katalogów, takiej jaksrc/fixture/models/isrc/fixture/labels/, aby wyczyścić organizację. -
Osadzanie w czasie kompilacji: użyj mechanizmów specyficznych dla języka, aby uwzględnić bajty modelu w pliku binarnym. W języku Rust użyj danych
include_bytes!binarnych iinclude_str!plików tekstowych. -
Zainicjuj wykres WASI-NN: w funkcji operatora
initutwórzwasi-nngraf na podstawie osadzonych bajtów, określając kodowanie ONNX i cel wykonywania procesora CPU. - Implementuj pętlę wnioskowania: dla każdego przychodzącego komunikatu przetworzyć dane wejściowe, aby były zgodne z wymaganiami modelu, ustawić tensory wejściowe, wykonywać wnioskowanie, pobrać dane wyjściowe i stosować przetwarzanie końcowe.
- Spokojna obsługa błędów: Zaimplementuj właściwą obsługę błędów podczas ładowania modelu, obsługi operatorów oraz błędów wnioskowania w czasie wykonywania.
Pełny wzorzec implementacji można znaleźć w przykładzie "snapshot".
Zalecana struktura projektu
Organizuj projekt modułu WASM z wyraźnym rozdzieleniem zagadnień:
src/
├── lib.rs # Main module implementation
├── model/
│ ├── mod.rs # Model management module
│ └── inference.rs # Inference logic
└── fixture/
├── models/
│ ├── mobilenet.onnx # Primary model
│ └── mobilenet_opt.onnx # Optimized variant
└── labels/
├── imagenet.txt # ImageNet class labels
└── custom.txt # Custom label mappings
Przykładowe odwołania do plików
Użyj następującego układu pliku z przykładu "snapshot" jako odwołania:
- Katalog etykiet — zawiera różne pliki mapowania etykiet
- Katalog Models — zawiera pliki i metadane modelu ONNX
Przykład minimalnego osadzania
W poniższym przykładzie pokazano minimalne osadzanie elementów Rust. Ścieżki są powiązane z plikiem źródłowym zawierającym makro:
// src/lib.rs (example)
// Embed ONNX model and label map into the component
static MODEL: &[u8] = include_bytes!("fixture/models/mobilenet.onnx");
static LABEL_MAP: &[u8] = include_bytes!("fixture/labels/synset.txt");
fn init_model() -> Result<(), anyhow::Error> {
// Create wasi-nn graph from embedded ONNX bytes using the CPU backend
// Pseudocode – refer to the snapshot sample for the full implementation
// use wasi_nn::{graph::{load, GraphEncoding, ExecutionTarget}, Graph};
// let graph = load(&[MODEL.to_vec()], GraphEncoding::Onnx, ExecutionTarget::Cpu)?;
// let exec_ctx = Graph::init_execution_context(&graph)?;
Ok(())
}
Optymalizacja wydajności
Aby uniknąć ponownego tworzenia grafu ONNX i kontekstu wykonywania dla każdego komunikatu, zainicjuj go raz i użyj go ponownie.
Przykład publiczny używa statycznego LazyLockelementu :
use crate::wasi::nn::{
graph::{load, ExecutionTarget, Graph, GraphEncoding, GraphExecutionContext},
tensor::{Tensor, TensorData, TensorDimensions, TensorType},
};
static mut CONTEXT: LazyLock<GraphExecutionContext> = LazyLock::new(|| {
let graph = load(&[MODEL.to_vec()], GraphEncoding::Onnx, ExecutionTarget::Cpu).unwrap();
Graph::init_execution_context(&graph).unwrap()
});
fn run_inference(/* input tensors, etc. */) {
unsafe {
// (*CONTEXT).compute()?;
}
}
Wdrażanie modułów
Użyj uproszczonych konstruktorów przykładów lub kompiluj lokalnie:
- Aby użyć uproszczonego konstruktora platformy Docker, zobacz Przykład narzędzia Rust Docker Builder
- Ogólne kroki wdrażania i rejestru zestawu WebAssembly można znaleźć w temacie Use WebAssembly with data flow graphs (Używanie zestawu WebAssembly z grafami przepływu danych)
Postępuj zgodnie z tym procesem wdrażania:
- Skompiluj moduł WASM w trybie kompilacji do wydania i utwórz plik
<module-name>-<version>.wasm. - Prześlij moduł oraz opcjonalnie definicję grafu do swojego rejestru, korzystając z rejestru OCI jako magazynu (ORAS).
- Utwórz lub użyj ponownie punktu końcowego rejestru w operacjach Azure IoT.
- Utwórz zasób grafu przepływu danych, który odwołuje się do artefaktu definicji grafu.
Przykład: klasyfikacja obrazów sieci MobileNet
Publiczne przykłady IoT udostępniają dwa przykłady wbudowane w graf do klasyfikacji obrazów: przykład "format" dostarcza funkcję dekodowania i zmiany rozmiaru obrazu, a przykład "migawka" zapewnia wnioskowanie ONNX i przetwarzanie softmax.
Aby wdrożyć ten przykład, należy ściągnąć artefakty z rejestru publicznego, wypchnąć je do rejestru i wdrożyć wykres przepływu danych, jak pokazano w przykładzie 2: Wdrażanie złożonego grafu. Złożony graf używa tych modułów do przetwarzania migawek obrazów i emitowania wyników klasyfikacji.
Ograniczenia
Wnioskowanie w grafach przepływu danych WASM ma następujące ograniczenia:
- Tylko ONNX. Wykresy przepływu danych nie obsługują innych formatów, takich jak TFLite.
- Tylko CPU. Brak przyspieszenia procesora GPU/TPU.
- Zalecane są małe modele. Duże modele i wnioskowanie intensywnie korzystające z pamięci nie są obsługiwane.
- Obsługiwane są modele wejściowe z pojedynczymi tensorami. Modele z wieloma danymi wejściowymi, buforowanie klucz-wartość i zaawansowane scenariusze sekwencji lub generowania nie są obsługiwane.
- Upewnij się, że zaplecze ONNX w środowisku uruchomieniowym WASM obsługuje operatory modelu. Jeśli operator nie jest obsługiwany, wnioskowanie kończy się niepowodzeniem podczas ładowania lub wykonywania.