Takip et

Her ML/AI Geliştiricisinin ONNX Hakkında Bilmesi Gerekenler

Her ML/AI Geliştiricisinin ONNX Hakkında Bilmesi Gerekenler Makine öğrenimi ve yapay zeka modelleri geliştirmek heyecan verici bir süreçtir,

Her ML/AI Geliştiricisinin ONNX Hakkında Bilmesi Gerekenler

Makine öğrenimi ve yapay zeka modelleri geliştirmek heyecan verici bir süreçtir, ancak bu modelleri üretim ortamına dağıtmak genellikle karmaşık bir hal alabilir. Farklı framework’ler (PyTorch, TensorFlow, Keras, scikit-learn vb.), farklı donanımlar (CPU, GPU, Edge cihazları) ve farklı işletim sistemleri arasında uyumluluk sorunları, geliştiricilerin karşısına çıkan en büyük engellerden biridir. İşte tam bu noktada ONNX (Open Neural Network Exchange) devreye girerek bu karmaşıklığı ortadan kaldırmayı hedefler.

Bu rehberde, her ML/AI geliştiricisinin ONNX hakkında bilmesi gereken temel bilgileri, pratik uygulamaları ve ipuçlarını bulacaksınız. ONNX’in ne olduğundan, modelleri nasıl dönüştüreceğinize, ONNX Runtime ile çıkarım (inference) yapmaya ve gelişmiş optimizasyon tekniklerine kadar geniş bir yelpazeyi ele alacağız.

ONNX Nedir ve Neden Önemlidir?

ONNX, makine öğrenimi modelleri için açık bir format standardıdır. Temel amacı, farklı makine öğrenimi framework’leri arasında model taşınabilirliğini ve birlikte çalışabilirliği sağlamaktır. Bir ONNX modeli, modelin hesaplama grafiğini (operatörler ve tensörler) ve önceden eğitilmiş ağırlıklarını içeren bir protokoldür.

ONNX’in Sağladığı Temel Avantajlar:

1. Framework Bağımsızlığı: Modellerinizi PyTorch’ta eğitip ONNX’e dönüştürebilir, ardından TensorFlow Lite veya başka bir ortamda dağıtabilirsiniz. Bu, geliştiricilere framework seçimi konusunda büyük bir esneklik sunar.
2. Performans Optimizasyonu: ONNX Runtime gibi yüksek performanslı çıkarım motorları, ONNX formatındaki modelleri CPU, GPU (NVIDIA CUDA, AMD ROCm), NPU gibi farklı donanım hızlandırıcılarında optimize edilmiş bir şekilde çalıştırabilir. Bu, genellikle orijinal framework’ün kendi çıkarım motorundan daha hızlı sonuçlar verir.
3. Dağıtım Kolaylığı: Tek bir standart format, modellerin bulut, sunucu, mobil ve edge cihazlar gibi çeşitli dağıtım hedeflerine kolayca entegre edilmesini sağlar.
4. Model Optimizasyonu: ONNX formatı, nicelikleştirme (quantization), grafik basitleştirme ve katman birleştirme gibi model optimizasyon tekniklerinin uygulanmasını kolaylaştırır. Bu, model boyutunu küçültür ve çıkarım hızını artırır.
5. Araştırma ve Üretim Köprüsü: Araştırma ekibiniz PyTorch kullanırken, üretim ekibiniz C++ tabanlı bir sistemde dağıtım yapıyorsa, ONNX bu iki dünya arasında sorunsuz bir köprü görevi görür.

Kısacası, ONNX makine öğrenimi modellerinin “evrensel dili” olmayı hedefler. Geliştiricilere daha fazla kontrol, esneklik ve performans sunar.

ONNX Modelleri Oluşturma ve Dönüştürme

Makine öğrenimi modellerini ONNX formatına dönüştürmek, genellikle eğitildiği framework’ün kendi araçları veya üçüncü taraf kütüphaneler aracılığıyla yapılır. İşte en yaygın kullanılan framework’lerden bazıları için örnekler:

PyTorch Modellerini ONNX’e Dönüştürme

PyTorch, modelleri ONNX’e aktarmak için yerleşik bir torch.onnx.export fonksiyonuna sahiptir.


import torch
import torch.nn as nn
import os

1. Basit bir PyTorch modeli tanımlayalım

class SimpleModel(nn.Module): def __init__(self): super(SimpleModel, self).__init__() self.fc1 = nn.Linear(10, 5) self.relu = nn.ReLU() self.fc2 = nn.Linear(5, 2) def forward(self, x): x = self.fc1(x) x = self.relu(x) x = self.fc2(x) return x model = SimpleModel()

2. Dummy giriş tensörü oluşturalım (modelin beklediği boyutta)

Bu, ONNX grafiğinin oluşturulması için gereklidir.

dummy_input = torch.randn(1, 10, requires_grad=True)

3. Modeli ONNX formatına aktaralım

onnx_path = "simple_model.onnx" torch.onnx.export( model, # Dönüştürülecek model dummy_input, # Modelin beklediği dummy giriş onnx_path, # Kaydedilecek ONNX dosyasının yolu export_params=True, # Eğitilmiş parametreleri dahil et opset_version=17, # ONNX operatör seti versiyonu (genellikle en güncel veya yaygın olan) do_constant_folding=True, # Sabit katlamayı etkinleştir (optimizasyon) input_names=['input'], # Giriş tensörünün adı output_names=['output'], # Çıkış tensörünün adı dynamic_axes={ # Dinamik eksenleri tanımla (değişken boyutlu girişler için) 'input': {0: 'batch_size'}, # Girişteki 0. eksen (batch) dinamik olabilir 'output': {0: 'batch_size'} # Çıkıştaki 0. eksen (batch) dinamik olabilir } ) print(f"Model {onnx_path} konumuna başarıyla kaydedildi.")

Kaydedilen ONNX dosyasını doğrulayalım

if os.path.exists(onnx_path): print("ONNX dosyası başarıyla oluşturuldu.") else: print("ONNX dosyası oluşturulamadı.")

Pratik İpuçları:

dummy_input: Bu, modelin ONNX grafiğini çıkarmak için kullanılan bir şablondur. Modelin beklediği tam* giriş boyutlarına ve veri tiplerine sahip olmalıdır.
* opset_version: ONNX operatör setinin versiyonunu belirtir. Genellikle en güncel stabil versiyonu kullanmak iyi bir fikirdir, ancak hedef dağıtım ortamınızın desteklediği versiyonu kontrol etmeniz gerekebilir.
* dynamic_axes: Özellikle değişken boyutlu girişlere (örneğin farklı batch boyutları) sahip modeller için kritik öneme sahiptir. Bu, ONNX Runtime’ın farklı giriş boyutlarıyla çalışmasını sağlar.
* input_names ve output_names: Bu isimler, ONNX modelini yüklerken giriş ve çıkış tensörlerini tanımlamak için kullanılır. Açıklayıcı isimler vermek kodu daha okunabilir hale getirir.

TensorFlow/Keras Modellerini ONNX’e Dönüştürme

TensorFlow veya Keras modellerini ONNX’e dönüştürmek için genellikle tf2onnx gibi üçüncü taraf araçlar kullanılır.


Kurulum

pip install tf2onnx onnx

Örnek dönüştürme komutu (bir saved_model için)

python -m tf2onnx.convert --saved-model /path/to/your/saved_model --output model.onnx --opset 17

Keras modelinden dönüştürme

from tf2onnx import convert

model = tf.keras.models.load_model('your_keras_model.h5')

spec = (tf.TensorSpec((None, 224, 224, 3), tf.float32, name="input"),)

output_path = "keras_model.onnx"

model_proto, _ = convert.from_keras(model, input_signature=spec, opset=17, output_path=output_path)

scikit-learn Modellerini ONNX’e Dönüştürme

skl2onnx kütüphanesi, scikit-learn modellerini ONNX’e dönüştürmek için kullanılır.


Kurulum

pip install skl2onnx onnx

Örnek (Logistic Regression)

from sklearn.linear_model import LogisticRegression

from skl2onnx import convert_sklearn

from skl2onnx.common.data_types import FloatTensorType

# # Model eğitme

model = LogisticRegression()

X = [[0., 1.], [1., 1.], [2., 2.]]

y = [0, 1, 0]

model.fit(X, y)

# # ONNX'e dönüştürme

initial_type = [('float_input', FloatTensorType([None, 2]))] # None: batch size

onnx_model = convert_sklearn(model, initial_types=initial_type)

# with open("skl_model.onnx", "wb") as f:

f.write(onnx_model.SerializeToString())

ONNX Runtime ile Çıkarım (Inference)

ONNX Runtime (ORT), ONNX formatındaki modelleri yüksek performansla çalıştırmak için tasarlanmış, çapraz platform bir çıkarım motorudur. Farklı donanım hızlandırıcılarını (CPU, GPU, DSP vb.) destekler ve modeli otomatik olarak optimize ederek en iyi performansı sağlamayı hedefler.

ONNX Runtime Kurulumu


CPU desteği için

pip install onnxruntime

GPU (CUDA) desteği için

pip install onnxruntime-gpu

ONNX Modeli ile Çıkarım Yapma


import onnxruntime as ort
import numpy as np
import torch # Sadece örnek input oluşturmak için

Daha önce kaydettiğimiz ONNX modelini yükleyelim

onnx_path = "simple_model.onnx"

1. ONNX Runtime InferenceSession oluşturalım

providers parametresi ile hangi donanım sağlayıcılarını kullanacağımızı belirleyebiliriz.

Varsayılan olarak 'CPUExecutionProvider' kullanılır.

Eğer GPU varsa: providers=['CUDAExecutionProvider', 'CPUExecutionProvider']

session = ort.InferenceSession(onnx_path, providers=['CPUExecutionProvider'])

2. Modelin giriş ve çıkış isimlerini ve beklediği veri tiplerini alalım

input_name = session.get_inputs()[0].name output_name = session.get_outputs()[0].name input_shape = session.get_inputs()[0].shape input_dtype = session.get_inputs()[0].type print(f"Model Giriş Adı: {input_name}, Şekil: {input_shape}, Veri Tipi: {input_dtype}") print(f"Model Çıkış Adı: {output_name}")

3. Giriş verisini hazırlayalım

ONNX Runtime, numpy dizilerini bekler. PyTorch tensörünü numpy'ye dönüştürelim.

Giriş boyutu ve veri tipi modelin beklediği gibi olmalı.

'float32' ONNX'teki 'tensor(float)' ile eşleşir.

input_data = torch.randn(1, 10).numpy().astype(np.float32)

4. Çıkarım (Inference) yapalım

session.run() metoduna çıkış isimleri listesi ve girişler sözlüğü verilir.

Giriş sözlüğü: {giriş_adı: giriş_verisi}

outputs = session.run([output_name], {input_name: input_data})

5. Sonuçları işleyelim

result = outputs[0] print(f"Çıkarım Sonucu (numpy array): {result}") print(f"Sonuç Şekli: {result.shape}, Veri Tipi: {result.dtype}")

Eğer birden fazla giriş veya çıkış varsa, get_inputs()/get_outputs() listesini

ve session.run() parametrelerini buna göre ayarlamanız gerekir.

Pratik İpuçları:

* Donanım Sağlayıcıları (providers): ort.InferenceSession oluştururken providers argümanını kullanarak hangi donanım hızlandırıcılarını kullanacağınızı belirtebilirsiniz. Örneğin, CUDA GPU kullanmak için ['CUDAExecutionProvider', 'CPUExecutionProvider'] listesini vermelisiniz. ONNX Runtime listedeki ilk uygun sağlayıcıyı kullanacaktır.
* Oturum Seçenekleri (SessionOptions): ort.SessionOptions() ile çıkarım oturumu üzerinde daha fazla kontrol sağlayabilirsiniz. Örneğin, graph_optimization_level ile grafik optimizasyon seviyesini ayarlayabilir veya intra_op_num_threads ile CPU çekirdek kullanımını yönetebilirsiniz.
* Giriş Verisi: Giriş verisinin NumPy dizisi olması ve modelin beklediği şekil (shape) ve veri tipine (dtype) tam olarak uyması gerektiğini unutmayın. Hatalı veri tipleri veya şekiller session.run() sırasında hataya yol açacaktır.
* Performans Ölçümü: Farklı sağlayıcılar ve oturum seçenekleriyle modelinizin performansını ölçerek en iyi konfigürasyonu bulmanız önemlidir.

ONNX’in Gelişmiş Kullanım Alanları ve Optimizasyon

ONNX, sadece modelleri dönüştürmek ve çalıştırmakla kalmaz, aynı zamanda modelleri daha verimli hale getirmek için çeşitli optimizasyon tekniklerine de olanak tanır.

Model Nicelikleştirme (Quantization)

Nicelikleştirme, modeldeki ağırlıkların ve aktivasyonların hassasiyetini düşürerek (örneğin, 32-bit float’tan 8-bit integer’a) model boyutunu küçültme ve çıkarım hızını artırma işlemidir. Özellikle mobil ve edge cihazlarda dağıtım için kritik bir optimizasyondur. ONNX Runtime, bu işlemi kolaylaştıran araçlar sunar.


Kurulum

pip install onnxruntime onnxruntime-extensions

from onnxruntime.quantization import quantize_dynamic, QuantFormat, onnx_model_utils

Giriş ONNX modelini dinamik nicelikleştirme ile optimize et

model_path = "simple_model.onnx" quantized_model_path = "simple_model_quantized.onnx"

Dinamik nicelikleştirme (ağırlıklar 8-bit int'e dönüştürülür, aktivasyonlar çalışma zamanında nicelikleştirilir)

quantize_dynamic( model_input=model_path, model_output=quantized_model_path, op_types_to_quantize=['MatMul', 'Gemm'], # Nicelikleştirilecek operatör tipleri per_channel=False, # Kanal başına nicelikleştirme yapılıp yapılmayacağı reduce_range=False, # Daha küçük aralıkta nicelikleştirme format=QuantFormat.QDQ # QDQ formatı (Quantize-Dequantize) ) print(f"Nicelikleştirilmiş model {quantized_model_path} konumuna kaydedildi.")

Nicelikleştirilmiş modeli test etme

session_quantized = ort.InferenceSession(quantized_model_path, providers=['CPUExecutionProvider']) input_data = torch.randn(1, 10).numpy().astype(np.float32) outputs_quantized = session_quantized.run([session_quantized.get_outputs()[0].name], {session_quantized.get_inputs()[0].name: input_data}) print(f"Nicelikleştirilmiş Model Çıkarım Sonucu: {outputs_quantized[0]}")

Grafik Optimizasyonları

ONNX Runtime, modelleri otomatik olarak optimize etmek için çeşitli grafik optimizasyonları uygular. Bunlar arasında düğüm birleştirme, ölü kod eliminasyonu ve katman füzyonu gibi teknikler bulunur. Bu optimizasyonlar, modelin hesaplama grafiğini basitleştirerek ve gereksiz işlemleri ortadan kaldırarak performansı artırır.

ONNX GraphSurgeon

Daha karmaşık model manipülasyonları için ONNX GraphSurgeon gibi araçlar kullanılabilir. Bu, ONNX grafiklerini programatik olarak düzenlemenize, düğümleri eklemenize, silmenize veya değiştirmenize olanak tanır. Özellikle özel operatörler eklemek veya mevcut operatörleri belirli donanımlara göre özelleştirmek istediğinizde faydalıdır.

Özel Operatörler (Custom Operators)

Eğer modeliniz standart ONNX operatör setinde bulunmayan özel bir katman veya işlem içeriyorsa, ONNX’e özel operatörler ekleyebilirsiniz. Bu, daha karmaşık veya niş modellerin ONNX ekosistemine entegrasyonunu sağlar. Ancak, bu durum genellikle daha fazla geliştirme çabası gerektirir ve dağıtım ortamınızın bu özel operatörleri desteklemesini sağlamanız gerekir.

Pratik İpuçları:

* Dengeyi Bulmak: Optimizasyonlar genellikle doğruluktan (accuracy) ödün vermeyi gerektirebilir. Nicelikleştirme gibi teknikleri uyguladıktan sonra modelinizin performansını ve doğruluğunu dikkatlice test etmelisiniz.
* Profil Oluşturma: Optimizasyon öncesi ve sonrası modelinizin çıkarım süresini ve bellek kullanımını profilleyerek, yapılan değişikliklerin gerçek faydalarını ölçün.
* İteratif Yaklaşım: Optimizasyon süreci genellikle iteratiftir. Küçük adımlarla başlayın, test edin ve gerektiğinde ayarlamalar yapın.

Sonuç ve Sıkça Sorulan Sorular (SSS)

ONNX, makine öğrenimi modellerinin geliştirilmesinden dağıtımına kadar tüm yaşam döngüsünü basitleştiren güçlü ve açık bir standarttır. Framework bağımsızlığı, yüksek performanslı çıkarım yetenekleri ve model optimizasyon araçlarıyla, her ML/AI geliştiricisinin araç setinde bulunması gereken önemli bir bileşendir. ONNX’i anlamak ve kullanmak, modellerinizi daha verimli, taşınabilir ve çeşitli ortamlara kolayca dağıtılabilir hale getirecektir.

Sıkça Sorulan Sorular (SSS)

ONNX hangi makine öğrenimi framework’lerini destekler?
ONNX; PyTorch, TensorFlow, Keras, scikit-learn, XGBoost, LightGBM ve daha birçok popüler framework’ü destekler. Desteklenen framework’lerden modelleri ONNX formatına dönüştürmek için ilgili kütüphaneler (örn. tf2onnx, skl2onnx) kullanılır.
ONNX Runtime neden genellikle orijinal framework’ün çıkarım motorundan daha hızlıdır?
ONNX Runtime (ORT), C++ ile yazılmış, yüksek performanslı bir çıkarım motorudur. Donanıma özel optimizasyonlar (örn. NVIDIA CUDA, Intel OpenVINO), gelişmiş grafik optimizasyonları ve verimli bellek yönetimi sayesinde, genellikle orijinal framework’lerin Python tabanlı çıkarım süreçlerinden daha hızlı çalışır.
ONNX modelimi nasıl görselleştirebilirim?
Netron, ONNX modellerini görselleştirmek için popüler ve ücretsiz bir araçtır. Modelin hesaplama grafiğini, operatörlerini, giriş/çıkış tensörlerini ve ağırlıklarını detaylı bir şekilde görmenizi sağlar.
Her makine öğrenimi modeli ONNX’e dönüştürülebilir mi?
Çoğu standart derin öğrenme ve geleneksel makine öğrenimi modeli ONNX’e başarıyla dönüştürülebilir. Ancak, çok özel veya deneysel operatörler içeren modeller için dönüştürme işlemi ek çaba gerektirebilir veya özel operatörlerin ONNX’e manuel olarak eklenmesini gerektirebilir.
ONNX ile ilgili daha fazla kaynak nerede bulabilirim?

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.
Exit mobile version