OpenVINO: Menjalankan Model AI dengan Cepat di CPU, iGPU, dan NPU Intel

# OpenVINO: Menjalankan Model AI dengan Cepat di CPU, iGPU, dan NPU Intel Halo temen-temen, di tutorial kali ini aku mau ngajak kalian kenalan sama OpenVINO, toolkit dari Intel yang tugasnya bikin mo...

By Ruby Abdullah · · tutorial
openvinointeledge-aiquantizationcpu-inference

OpenVINO: Menjalankan Model AI dengan Cepat di CPU, iGPU, dan NPU Intel

Halo temen-temen, di tutorial kali ini aku mau ngajak kalian kenalan sama OpenVINO, toolkit dari Intel yang tugasnya bikin model AI jalan cepat di hardware yang kalian punya sekarang, tanpa harus beli GPU NVIDIA. Iya, kalian baca dengan benar. Banyak use case AI di dunia nyata itu tidak butuh GPU mahal. Yang mereka butuhkan adalah inference yang cepat dan hemat di CPU biasa, di integrated GPU laptop, atau di NPU yang sekarang mulai ada di prosesor generasi baru.

Aku sering ketemu kasus begini di klien: mereka mau deteksi objek di 10 kamera CCTV di pabrik, atau mau OCR dokumen di komputer kantor, atau mau menjalankan asisten AI di laptop karyawan secara offline karena datanya sensitif. Beli GPU untuk semua titik itu tidak masuk akal secara biaya. Di situlah OpenVINO jadi jawaban yang sangat praktis.

Di tutorial ini kita bahas konsep dasarnya, instalasi, konversi model dari PyTorch dan ONNX, inference dengan Python, kuantisasi INT8 dengan NNCF, menjalankan LLM lokal, sampai tips memilih perangkat dan mengukur performa dengan benar.

Introduction

Apa Itu OpenVINO

OpenVINO singkatan dari Open Visual Inference and Neural Network Optimization. Meskipun namanya menyebut visual, sekarang dia mendukung hampir semua jenis model, termasuk LLM dan model audio.

Idenya seperti ini. Model kalian yang ditulis di PyTorch atau TensorFlow diubah menjadi representasi perantara milik OpenVINO yang disebut IR (Intermediate Representation), berupa file .xml yang menjelaskan struktur graf dan file .bin yang berisi bobot. Runtime OpenVINO kemudian mengeksekusi IR itu dengan kernel yang dioptimasi untuk hardware Intel: instruksi AVX-512 dan AMX di CPU, kernel khusus di integrated GPU, dan akselerator khusus di NPU.

Keunggulan utamanya ada empat. Pertama, satu API untuk banyak perangkat, kalian cukup mengganti string "CPU" menjadi "GPU" atau "NPU". Kedua, optimasi CPU yang sangat serius, sering memberi percepatan dua sampai empat kali dibanding menjalankan model PyTorch apa adanya. Ketiga, dukungan kuantisasi INT8 yang matang lewat NNCF. Keempat, ukuran runtime yang kecil sehingga cocok untuk edge deployment.

Kapan OpenVINO Masuk Akal

OpenVINO masuk akal kalau deployment kalian di CPU atau di perangkat edge Intel, kalau kalian butuh menjalankan banyak instance model kecil sampai menengah secara paralel dengan biaya rendah, kalau data kalian tidak boleh keluar dari perangkat sehingga inference harus lokal, atau kalau kalian ingin memanfaatkan integrated GPU yang selama ini menganggur di ribuan laptop kantor.

OpenVINO kurang cocok kalau kalian melatih model (dia murni untuk inference), kalau kalian butuh menjalankan LLM sangat besar dengan throughput tinggi (itu ranah GPU dedicated), atau kalau stack kalian sudah terikat kuat ke ekosistem NVIDIA.

Instalasi

python -m venv venv

source venv/bin/activate # Linux / Mac

venv\Scripts\activate # Windows

pip install openvino openvino-dev

pip install "optimum[openvino]" # untuk model HuggingFace

pip install nncf # untuk kuantisasi

Cek perangkat apa saja yang terdeteksi di mesin kalian:

import openvino as ov

core = ov.Core()

print("perangkat tersedia:", core.availabledevices)

for d in core.availabledevices:

print(d, "->", core.getproperty(d, "FULLDEVICENAME"))

Biasanya kalian akan melihat CPU, dan kalau prosesor kalian punya integrated graphics, akan muncul GPU juga. Di prosesor Core Ultra generasi baru, NPU akan muncul.

Konversi Model dari PyTorch

Cara paling langsung adalah mengonversi model PyTorch yang sudah kalian punya.

import torch

import openvino as ov

import torchvision

1. Siapkan model PyTorch

model = torchvision.models.resnet50(weights="IMAGENET1KV2")

model.eval()

2. Konversi ke OpenVINO

contohinput = torch.randn(1, 3, 224, 224)

ovmodel = ov.convertmodel(model, exampleinput=contohinput)

3. Simpan sebagai IR

ov.savemodel(ovmodel, "resnet50.xml")

Setelah ini kalian punya resnet50.xml dan resnet50.bin. Dua file itu yang kalian bawa ke mesin produksi, tanpa perlu menginstal PyTorch di sana. Ini poin penting yang sering diremehkan: runtime OpenVINO jauh lebih ringan daripada PyTorch, dan itu berarti image Docker kalian bisa menyusut drastis.

Untuk model ONNX, konversinya bahkan lebih sederhana karena OpenVINO bisa membaca ONNX secara langsung:

import openvino as ov

core = ov.Core()

model = core.readmodel("model.onnx")

compiled = core.compilemodel(model, "CPU")

Inference Pertama

Ini pola dasar yang akan kalian pakai berulang kali.

import numpy as np

import openvino as ov

from PIL import Image

core = ov.Core()

1. Baca dan kompilasi model untuk perangkat tertentu

model = core.readmodel("resnet50.xml")

compiled = core.compilemodel(model, "CPU")

2. Siapkan input

img = Image.open("gambar.jpg").convert("RGB").resize((224, 224))

x = np.array(img).astype(np.float32) / 255.0

mean = np.array([0.485, 0.456, 0.406])

std = np.array([0.229, 0.224, 0.225])

x = (x - mean) / std

x = x.transpose(2, 0, 1)[None].astype(np.float32) # NCHW

3. Jalankan

hasil = compiled(x)[compiled.output(0)]

4. Ambil top-5

top5 = np.argsort(-hasil[0])[:5]

print("indeks kelas teratas:", top5)

print("skor:", hasil[0][top5])

Perhatikan bahwa compilemodel adalah tahap yang memakan waktu, karena di situlah OpenVINO memilih kernel dan mengoptimasi graf untuk perangkat target. Lakukan sekali saat aplikasi kalian start, jangan di dalam loop request.

Inference Asinkron

Untuk throughput tinggi, jangan pakai pola sinkron di atas. Pakai antrian inference asinkron supaya CPU tidak menganggur menunggu.

import openvino as ov

import numpy as np

core = ov.Core()

model = core.readmodel("resnet50.xml")

compiled = core.compilemodel(model, "CPU", {"PERFORMANCEHINT": "THROUGHPUT"})

hasilsemua = []

def simpan(request, userdata):

hasilsemua.append((userdata, request.getoutputtensor(0).data.copy()))

antrian = ov.AsyncInferQueue(compiled)

antrian.setcallback(simpan)

batchgambar = [np.random.randn(1, 3, 224, 224).astype(np.float32) for in range(100)]

for i, gambar in enumerate(batchgambar):

antrian.startasync({0: gambar}, userdata=i)

antrian.waitall()

print("selesai memproses", len(hasilsemua), "gambar")

PERFORMANCEHINT punya dua nilai utama. LATENCY mengoptimasi waktu respons satu request, cocok untuk aplikasi interaktif. THROUGHPUT mengoptimasi jumlah total request per detik dengan menjalankan beberapa stream paralel, cocok untuk pemrosesan batch atau server. Pilih sesuai kebutuhan, ini salah satu tombol dengan dampak terbesar.

Kuantisasi INT8 dengan NNCF

Kuantisasi mengubah bobot dan aktivasi dari fp32 menjadi int8. Modelnya jadi sekitar empat kali lebih kecil dan inference-nya biasanya dua sampai tiga kali lebih cepat di CPU modern, dengan penurunan akurasi yang biasanya di bawah satu persen kalau dilakukan dengan benar.

import nncf

import openvino as ov

import numpy as np

from torch.utils.data import DataLoader

core = ov.Core()

model = core.readmodel("resnet50.xml")

Data kalibrasi: 100 sampai 300 sampel representatif sudah cukup

def transformfn(item):

gambar, = item

return gambar.numpy()

calibrationloader = DataLoader(datasetvalidasi, batchsize=1, shuffle=True)

calibrationdataset = nncf.Dataset(calibrationloader, transformfn)

modelint8 = nncf.quantize(

model,

calibrationdataset,

preset=nncf.QuantizationPreset.MIXED,

subsetsize=300,

)

ov.savemodel(modelint8, "resnet50int8.xml")

Poin penting soal data kalibrasi: ambil dari distribusi data nyata kalian, bukan data acak. Kalau model kalian nanti melihat citra CCTV pabrik yang gelap dan berbayang, jangan kalibrasi dengan foto stok yang terang benderang. Kualitas kuantisasi sangat bergantung pada ini.

Dan selalu ukur ulang akurasi setelah kuantisasi di data validasi kalian sendiri. Kalau turunnya lebih dari yang bisa kalian terima, coba preset=nncf.QuantizationPreset.PERFORMANCE diganti ke mode yang lebih konservatif, atau kecualikan beberapa layer sensitif dari kuantisasi.

Menjalankan Model HuggingFace

Lewat pustaka Optimum Intel, hampir semua model HuggingFace bisa dijalankan dengan OpenVINO tanpa konversi manual.

from optimum.intel import OVModelForSequenceClassification

from transformers import AutoTokenizer

modelid = "distilbert-base-uncased-finetuned-sst-2-english"

tokenizer = AutoTokenizer.frompretrained(modelid)

model = OVModelForSequenceClassification.frompretrained(modelid, export=True)

model.savepretrained("distilbert-ov")

inputs = tokenizer("Filmnya bagus banget, aku suka.", returntensors="pt")

logits = model(inputs).logits

print(logits.argmax(-1))

Argumen export=True memicu konversi otomatis dari bobot PyTorch ke IR OpenVINO. Setelah disimpan, panggilan berikutnya cukup memuat dari direktori lokal tanpa proses konversi lagi.

Menjalankan LLM Lokal

Ini use case yang sekarang paling sering ditanyakan. Menjalankan LLM kecil di laptop, sepenuhnya offline.

from optimum.intel import OVModelForCausalLM

from transformers import AutoTokenizer

modelid = "TinyLlama/TinyLlama-1.1B-Chat-v1.0"

tokenizer = AutoTokenizer.frompretrained(modelid)

model = OVModelForCausalLM.frompretrained(modelid, export=True)

prompt = "Jelaskan apa itu edge computing dalam tiga kalimat."

inputs = tokenizer(prompt, returntensors="pt")

out = model.generate(inputs, maxnewtokens=200, dosample=True, temperature=0.7)

print(tokenizer.decode(out[0], skipspecialtokens=True))

Untuk performa yang layak di CPU, kalian hampir pasti perlu kuantisasi bobot. Cara termudah lewat command line:

optimum-cli export openvino \

--model TinyLlama/TinyLlama-1.1B-Chat-v1.0 \

--weight-format int4 \

--group-size 128 \

--ratio 0.8 \

tinyllama-ov-int4

Lalu muat hasilnya:

model = OVModelForCausalLM.frompretrained("tinyllama-ov-int4")

Dengan INT4, model 1 miliar parameter turun jadi sekitar 700 MB dan bisa berjalan dengan kecepatan yang nyaman dibaca manusia bahkan di laptop tanpa GPU dedicated. Untuk model 7B, kalian butuh RAM sekitar 5 sampai 6 GB dan kecepatannya akan lebih lambat, tapi masih bisa dipakai untuk tugas non-interaktif.

Memilih Perangkat

Mengganti perangkat cuma soal mengganti string, tapi ada pertimbangan yang perlu kalian tahu.

CPU adalah pilihan paling universal dan paling matang. Untuk model kecil dan menengah, sering kali sudah sangat memadai, terutama di prosesor server dengan AMX. GPU di sini berarti integrated GPU Intel. Dia biasanya lebih hemat energi dan lebih cepat dari CPU untuk model vision, tapi transfer data ke memori GPU punya overhead, jadi untuk model yang sangat kecil kadang CPU malah menang. NPU tersedia di prosesor Core Ultra dan sangat hemat daya. Cocok untuk model yang berjalan terus menerus di latar belakang, misalnya deteksi wajah atau background blur. Dukungan operatornya masih lebih terbatas dibanding CPU. AUTO membiarkan OpenVINO memilihkan perangkat terbaik dan bahkan bisa mulai di CPU sambil menunggu GPU siap dikompilasi.
compiled = core.compilemodel(model, "AUTO")

Dan MULTI atau HETERO memungkinkan kalian membagi beban ke beberapa perangkat sekaligus.

compiled = core.compilemodel(model, "MULTI:GPU,CPU")

Mengukur Performa dengan Benar

OpenVINO menyediakan alat benchmark yang sebaiknya kalian pakai daripada mengukur dengan time.time() sendiri.

benchmarkapp -m resnet50.xml -d CPU -hint throughput -t 30

benchmarkapp -m resnet50int8.xml -d CPU -hint throughput -t 30

Perhatikan dua angka di outputnya: latensi rata-rata dan throughput dalam FPS. Bandingkan versi fp32 dan int8 kalian di sini. Kalau percepatannya kurang dari yang kalian harapkan, biasanya karena model kalian terlalu kecil sehingga overhead framework mendominasi, atau karena kalian mengukur dengan hint yang salah.

Tips dan Best Practice

Kompilasi model sekali saja saat aplikasi start, jangan per request. Ini kesalahan performa nomor satu yang aku lihat.

Gunakan model cache supaya kompilasi berikutnya lebih cepat, terutama untuk GPU dan NPU.

core.setproperty({"CACHEDIR": "./ovcache"})

Pilih PERFORMANCEHINT sesuai beban kerja, dan uji keduanya. Perbedaan antara LATENCY dan THROUGHPUT bisa mencapai dua kali lipat di arah yang berlawanan.

Untuk aplikasi video, jangan proses frame satu per satu secara sinkron. Pakai AsyncInferQueue dan biarkan pipeline terisi.

Simpan IR hasil konversi di repositori artefak kalian, bukan mengonversi ulang di setiap deployment. Konversi itu deterministik dan tidak perlu diulang.

Selalu bandingkan akurasi sebelum dan sesudah kuantisasi di data kalian sendiri, bukan di benchmark publik.

Perhatikan jumlah thread. Kalau kalian menjalankan beberapa proses inference di satu mesin, batasi thread per proses supaya mereka tidak saling berebut inti CPU.

core.setproperty("CPU", {"INFERENCENUMTHREADS": 4})

Kesimpulan

OpenVINO adalah alat yang membuat AI jadi jauh lebih terjangkau, karena dia memanfaatkan hardware yang sudah kalian miliki. Ringkasan pentingnya:

Model dikonversi ke format IR sekali, lalu dijalankan runtime ringan yang tidak butuh PyTorch di mesin produksi.

Satu API yang sama melayani CPU, integrated GPU, dan NPU, cukup dengan mengganti string perangkat.

Kuantisasi INT8 lewat NNCF memberi percepatan besar dengan penurunan akurasi kecil, asalkan data kalibrasinya representatif.

Untuk model HuggingFace dan LLM lokal, Optimum Intel membuat konversi jadi satu baris, dan INT4 membuat LLM kecil nyaman dijalankan di laptop.

Gunakan AsyncInferQueue dan PERFORMANCEHINT yang tepat untuk mendapatkan throughput sebenarnya, lalu verifikasi dengan benchmark_app.

Coba ambil satu model klasifikasi atau deteksi yang sudah kalian punya, konversi ke OpenVINO, kuantisasi ke INT8, lalu bandingkan angkanya dengan versi PyTorch di CPU yang sama. Banyak orang kaget waktu tahu mereka sebenarnya tidak butuh GPU untuk use case yang sedang mereka kerjakan. Selamat mencoba.

Artikel Terkait

TensorRT-LLM: Memeras Throughput Maksimal dari GPU NVIDIA untuk Inference LLM

TensorRT-LLM: Memeras Throughput Maksimal dari GPU NVIDIA untuk Inference LLM Halo temen-temen, kali ini kita bahas sala...

Moondream: Vision-Language Model Mungil buat Tanya-Jawab Gambar, Caption, Deteksi, dan Pointing

Moondream: Vision-Language Model Mungil buat Tanya-Jawab Gambar, Caption, Deteksi, dan Pointing Halo temen-temen, di tut...

llama.cpp dan GGUF Quantization: Deploy LLM Secara Lokal

llama.cpp dan GGUF Quantization: Deploy LLM Secara Lokal Pendahuluan Menjalankan Large Language Model (LLM) secara lokal...

Tutorial TensorFlow Lite: Deploy ML di Mobile dan Edge Device

Tutorial 18: TensorFlow Lite - Deploy ML di Perangkat Mobile Daftar Isi Pendahuluan Prasyarat Memahami TensorFlow Lite [...