Ana Sayfa/Java & Kurumsal Mimari
Java & Kurumsal Mimari·18 Ekim 2026·7 dk okuma

JNI ve Python Köprülerine Veda: TornadoVM 7.2.0, Tensor Core (mma.sync) Entegrasyonu ve Saf Java ile GPU Üzerinde LLM Çıkarımı

Standart Java bayt kodunu çalışma zamanında NVIDIA PTX, OpenCL, SPIR-V ve Apple Metal çekirdeklerine derleyen TornadoVM 7.2.0 mimarisi, Project Panama sıfır-kopya bellek yönetimi ve jitLLM ile yerel GPU hızlandırma analizi.

JNI ve Python Köprülerine Veda: TornadoVM 7.2.0, Tensor Core (mma.sync) Entegrasyonu ve Saf Java ile GPU Üzerinde LLM Çıkarımı

Kurumsal Java’nın "Python Vergisi" ve Heterojen Hesaplama Darboğazı

Yıllar boyunca kurumsal bir Java (Spring Boot veya Quarkus) uygulamasında yüksek yoğunluklu matris çarpımı, görüntü işleme veya Büyük Dil Modeli (LLM) çıkarımı yapmak isteyen mühendislik ekipleri, iki maliyetli seçenek arasında sıkışıp kalmıştı: ya bakımı son derece kırılgan olan JNI (Java Native Interface) + C++/CUDA sarmalayıcıları yazmak ya da sırf GPU’ya erişebilmek için Java servisinin yanına ayrı bir Python/PyTorch mikroservisi ayağa kaldırıp gRPC/HTTP üzerinden serileştirme gecikmesi (serialization tax) ödemek.

Манчестер Üniversitesi (University of Manchester) APT Grubu öncülüğünde geliştirilen açık kaynaklı heterojen JVM yürütme motoru TornadoVM, 7.2.0 sürümü ve ekosistemindeki jitLLM (GPULlama3.java) araç setiyle bu mimari ikilemi ortadan kaldırıyor. Standart Java bayt kodunu çalışma zamanında (JIT) doğrudan NVIDIA CUDA (PTX), OpenCL C, SPIR-V (Intel Level-Zero) ve Apple Silicon Metal (MSL) makine koduna dönüştüren TornadoVM 7.2.0; artık Tensor Core (mma.sync) komutlarını, Project Panama (MemorySegment) sıfır-kopya (zero-copy) bellek yönetimini ve yerel cuBLAS / cuDNN / cuTile kütüphanelerini tek satır C++ kodu yazmadan doğrudan Java geliştiricisinin emrine sunuyor.

"Bir Java uygulamasının GPU üzerinde matris çarpımı veya LLM çıkarımı yapabilmesi için ayrı bir Python konteynerine ağ üzerinden JSON göndermesi, modern donanım mimarisine ödenen en gereksiz gecikme vergisidir."


1. TornadoVM 7.2.0’ın JIT Derleme Boru Hattı: Java Bayt Kodundan PTX, OpenCL ve Metal’e

Standart HotSpot JVM, Java bayt kodunu yalnızca CPU mimarileri (x86_64 veya AArch64) için derler. TornadoVM ise GraalVM JIT derleyicisinin üstüne inşa edilen özel bir Heterojen Graal IR (Intermediate Representation) katmanı kullanır:

  1. Bildirimsel Paralellik (@Parallel ve @Reduce) veya Açık Çekirdek API’si (KernelContext): Geliştirici standart Java döngülerine yalnızca @Parallel veya @Reduce anotasyonları ekler ya da paylaşımlı GPU belleği (local/shared memory) ve iş parçacığı bariyerleri üzerinde tam kontrol sağlayan KernelContext API’sini kullanır.
  2. Graal IR’dan Donanım Komut Setine Dinamik Çeviri: TornadoVM çalışma zamanında (runtime) Java bayt kodunu analiz eder, veri bağımlılık grafiğini çıkarır ve hedef donanıma göre en uygun arka uca derler:
    • NVIDIA GPU’lar (PTX / cubin): Doğrudan NVIDIA sürücüsüne gönderilen PTX kodunu üretir. 7.2.0 serisiyle birlikte eşzamansız bellek kopyalama (cp.async), warp düzeyinde oylama (warp-vote) ve Tensor Core (mma.sync) içsel komutları (intrinsics) doğrudan desteklenir.
    • Apple Silicon (Metal Shading Language - MSL): M1–M5 serisi çiplerde birleşik belleği (Unified Memory) kullanarak doğrudan Metal GPU çekirdekleri üretir.
    • OpenCL & SPIR-V: AMD, Intel Arc ve ARM GPU’ların yanı sıra FPGA hızlandırıcılar üzerinde çapraz platform uyumluluğu sağlar.

2. Project Panama (MemorySegment), Tensor API ve Sıfır-Kopya (Zero-Copy) Bellek

GPU programlamada en büyük performans katili hesaplama süresi değil, verinin JVM Yığınından (Heap) PCIe veri yolu üzerinden GPU HBM/GDDR belleğine kopyalanmasıdır. Klasik Java dizileri (float[]) Çöp Toplayıcı (GC) tarafından bellekte taşınabildiği için GPU DMA (Direct Memory Access) motorları tarafından doğrudan okunamaz.

TornadoVM 7.2.0, Java’nın Project Panama (Foreign Function & Memory API) altyapısını ve yerleşik Tensor veri tiplerini derinlemesine entegre ederek bu darboğazı çözer:

  • Yığın-Dışı (Off-Heap) MemorySegment ve Sıfır-Kopya Dilimleme: FloatArray, HalfFloatArray (FP16), Int8Array ve TensorFP16 gibi veri yapıları doğrudan Panama MemorySegment üzerinde yığın-dışı (off-heap) hizalanmış olarak tutulur. Böylece serileştirme veya ekstra tampon kopyalama maliyeti sıfırlanır.
  • Görev Grafiği (TaskGraph) ve Tembel Kopyalama (Lazy Copy-Out): Birden fazla GPU çekirdeği bir TaskGraph içinde zincirlendiğinde, ara sonuçlar CPU’ya geri dönmeden GPU belleğinde (DeviceResident) kalır; yalnızca son katmanın çıktısı gerektiğinde (DataTransferMode.UNDER_DEMAND) ana belleğe çekilir.
  • Yerel Kütüphane Köprüsü (cuBLAS, cuFFT, cuDNN, cuTile): Kendi çekirdeğinizi yazmak istemediğiniz noktalarda TornadoVM 7.2.0, görev grafiği içinden doğrudan NVIDIA’nın donanım optimize cuBLAS ve cuTile rutinlerini çağırabilir.
Mimari Özellik TornadoVM 7.2.0 + jitLLM Geleneksel JNI + C++ Sarmalayıcı Harici Python / PyTorch Mikroservisi
Dil & Tip Güvenliği %100 Saf Java (JDK 21–28, GraalVM + Panama) Çift Dil (Java + C++/CUDA), yüksek çökme riski Çift Teknoloji Yığını (Java + Python)
Donanım Taşınabilirliği Tek kodla NVIDIA PTX, AMD/Intel OpenCL, Apple Metal Yalnızca yazıldığı API (örn. sadece CUDA) PyTorch/vLLM sürücü bağımlılıkları
Bellek Transferi Panama MemorySegment + TaskGraph Cihaz-İçi Kalıcılık Manuel cudaMemcpy ve JNI Pinning Ağ üzerinden JSON/Protobuf serileştirme
Tensor Core & Kütüphane Doğrudan mma.sync, cp.async, cuBLAS, cuDNN Manuel C++ şablonları (CUTLASS) gerektirir C++ arka uçta gizli, Java'dan erişilemez
Kurumsal Entegrasyon Quarkus & LangChain4j içinde yerel (in-process) çalışır Konteyner ve sürücü bağımlılığı karmaşık Ayrı pod, ayrı ölçekleme ve ağ gecikmesi

3. Saf Java ile GPU Hızlandırma: TornadoVM 7.2.0 Kod Örneği

Aşağıdaki Java örneği, TornadoVM 7.2.0 kullanarak yığın-dışı (FloatArray / Tensor) bellek üzerinde çalışan bir Matris Çarpımı ve RMSNorm (LLM Katmanı) boru hattının tek bir TaskGraph içinde GPU üzerinde nasıl yürütüldüğünü göstermektedir:

java
import uk.ac.manchester.tornado.api.TaskGraph;
import uk.ac.manchester.tornado.api.TornadoExecutionPlan;
import uk.ac.manchester.tornado.api.annotations.Parallel;
import uk.ac.manchester.tornado.api.annotations.Reduce;
import uk.ac.manchester.tornado.api.enums.DataTransferMode;
import uk.ac.manchester.tornado.api.math.TornadoMath;
import uk.ac.manchester.tornado.api.types.arrays.FloatArray;
import uk.ac.manchester.tornado.api.types.matrix.Matrix2DFloat;

public class TornadoGpuTransformerLayer {

    // 1. GPU Çekirdeği: 2 Boyutlu Paralel Matris Çarpımı (PTX / Metal / OpenCL JIT)
    public static void matrixMultiply(
            Matrix2DFloat A, Matrix2DFloat B, Matrix2DFloat C, final int size) {
        for (@Parallel int i = 0; i < size; i++) {
            for (@Parallel int j = 0; j < size; j++) {
                float sum = 0.0f;
                for (int k = 0; k < size; k++) {
                    sum += A.get(i, k) * B.get(k, j);
                }
                C.set(i, j, sum);
            }
        }
    }

    // 2. GPU Çekirdeği: Paralel İndirgeme (@Reduce) ile Kareler Toplamı
    public static void computeSumOfSquares(FloatArray x, @Reduce FloatArray sumSq) {
        sumSq.set(0, 0.0f);
        for (@Parallel int i = 0; i < x.getSize(); i++) {
            float val = x.get(i);
            sumSq.set(0, sumSq.get(0) + (val * val));
        }
    }

    // 3. GPU Çekirdeği: Eleman Bazlı RMSNorm Normalizasyonu
    public static void applyRmsNorm(
            FloatArray x, FloatArray weights, FloatArray out, FloatArray sumSq, int n) {
        float rms = 1.0f / TornadoMath.sqrt((sumSq.get(0) / n) + 1e-5f);
        for (@Parallel int i = 0; i < n; i++) {
            out.set(i, x.get(i) * rms * weights.get(i));
        }
    }

    public static void main(String[] args) {
        final int dim = 4096;
        // Project Panama (MemorySegment) tabanlı yığın-dışı (off-heap) bellek tahsisi
        FloatArray input = new FloatArray(dim);
        FloatArray normWeights = new FloatArray(dim);
        FloatArray sumSq = new FloatArray(1);
        FloatArray normalizedOut = new FloatArray(dim);

        input.init(0.5f);
        normWeights.init(1.0f);

        // Görev Grafiği: Ara veri (sumSq) CPU'ya dönmeden doğrudan GPU HBM'de kalır!
        TaskGraph taskGraph = new TaskGraph("llm-norm-pipeline")
                .transferToDevice(DataTransferMode.FIRST_EXECUTION, input, normWeights)
                .task("sum-squares", TornadoGpuTransformerLayer::computeSumOfSquares, input, sumSq)
                .task("rms-norm", TornadoGpuTransformerLayer::applyRmsNorm,
                        input, normWeights, normalizedOut, sumSq, dim)
                .transferToHost(DataTransferMode.EVERY_EXECUTION, normalizedOut);

        try (TornadoExecutionPlan executionPlan = new TornadoExecutionPlan(taskGraph.snapshot())) {
            // Warm-up (Bayt kodundan PTX/SPIR-V/Metal'e JIT derleme) ve GPU yürütmesi
            executionPlan.withWarmUp().execute();
            System.out.println("GPU RMSNorm Çıktı[0]: " + normalizedOut.get(0));
        }
    }
}

4. jitLLM ve GPULlama3.java: Quarkus ve LangChain4j İçinde Yerel LLM Motoru

TornadoVM 7.2.0’ın en çarpıcı pratik sonucu, GPULlama3.java projesinin evrilmesiyle ortaya çıkan jitLLM (Java Inference Tornado Toolkit) çalışma zamanıdır. jitLLM, tek bir satır Python veya C++ bağımlılığı olmadan standart GGUF formatındaki modelleri (Llama 3.x, Qwen 2.5/3, Mistral, Phi-3 ve DeepSeek-R1-Distill) doğrudan JVM içinde GPU üzerinde koşturur:

  • Birleştirilmiş Niceleme Çekirdekleri (Fused Dequantize-Compute Kernels): FP16 ve Q8_0 / Q4 nicelemeli ağırlıklar CPU’da açılmak yerine doğrudan TornadoVM KernelContext çekirdekleri içinde GPU yazmaçlarında (registers) çözülüp matris çarpımına sokulur.
  • LangChain4j ve Quarkus Entegrasyonu: jitLLM, resmi olarak LangChain4j yerel sağlayıcısı ve Quarkus uzantısı olarak çalışır. Bu sayede kurumsal bir Java mikroservisi, veri gizliliği (KVKK/GDPR) gerektiren doküman özetleme veya gömme (embedding) işlemlerini kendi JVM süreci içinden doğrudan sunucudaki GPU’ya devredebilir.
  • Project Babylon (Code Reflection) ile Gelecek Sinerjisi: OpenJDK’nın Project Babylon (Kod Yansıması) çalışmalarıyla birleştiğinde, TornadoVM’in gelecekteki sürümleri Java lambda ifadelerini bayt kodu analizine bile gerek kalmadan doğrudan tip-güvenli GPU çekirdek ağaçlarına dönüştürecektir.

5. Mühendislik Ekipleri İçin Mimari Karar Rehberi

  1. Mikroservis Sadeleştirmesi: Yalnızca yerel embedding üretimi, yeniden sıralama (reranking) veya orta ölçekli (7B–14B) GGUF model çıkarımı için Java kümenizin yanında ayrı bir Python/FastAPI servisi tutuyorsanız, TornadoVM 7.2.0 + jitLLM + Quarkus üçlüsüyle bu katmanı tamamen JVM içine alabilirsiniz.
  2. Veri Transferini Minimize Edin (DataTransferMode.FIRST_EXECUTION): Model ağırlıklarını ve sabit matrisleri her istekte GPU’ya göndermek yerine FIRST_EXECUTION bayrağıyla GPU VRAM’ine sabitleyin; her istekte yalnızca girdi token dizisini (EVERY_EXECUTION) aktarın.
  3. Çoklu-Donanım Özgürlüğü: Kodunuzu CUDA C++’a kilitlemek yerine TornadoVM TaskGraph soyutlamasıyla yazdığınızda, geliştirici bilgisayarındaki Apple M-serisi (Metal) GPU’da geliştirdiğiniz kodu üretim ortamındaki NVIDIA H100/B200 (PTX) veya AMD Instinct (OpenCL) sunucularda değiştirmeden çalıştırabilirsiniz.
Konu Etiketleri
#Java#JVM#TornadoVM#GPU#CUDA#ProjectPanama#jitLLM#Quarkus#LangChain4j
Emre Taştutan
Emre TaştutanGeliştirici & AI Meraklısı

Yazılım mimarisi, mikroservis ekosistemleri ve üretken yapay zeka uygulamaları üzerine çalışıyorum. TastutanLabs çatısı altında geliştirici araçları ve SaaS ürünleri inşa ediyorum.

@tastutanlabs • Instagram Mini-Blog

Bu analizin 6 kartlık görsel özetini Instagram'da inceleyin ve kaydedin

Her gün yazılım mimarisi, Java/JVM ve yapay zeka gelişmelerini kendi başına okunabilen 6 slaytlık Mini-Blog serileri halinde paylaşıyoruz.

Instagram'da Takip Et →
Bu Yazıyı Paylaş:

Yorumlar (0)

Düşüncelerinizi Paylaşın

Henüz yorum yapılmamış. İlk yorumu siz yapın!

Bu Kategorideki Diğer İncelemeler

Java & Kurumsal Mimari

P1 Seviyesi Derleyici Krizinden AI Donanım Hızlandırmasına: JDK 28’in Mimari Rotası, Babylon-Valhalla Sinerjisi ve JVM vs. Rust Performans Hesaplaşması

JDK 27 RC aşamasında yakalanan P1 seviyesi String bozulması hatasının anatomisi, Paul Sandoz’un çizdiği Project Babylon/Valhalla tabanlı AI vizyonu, JEP 545 ZGC ile JEP 540 JSON API'nin perde arkası ve Spring ekosisteminde AI destekli JVM vs. Rust kıyaslamalarının derinlemesine analizi.

Emre TaştutanEmre Taştutan
14 dk
Java & Kurumsal Mimari

Yıkmadan İnşa Etmek: OCX 2026 Işığında Jakarta EE 12, "Veri Çağı" Mimarisi ve Kurumsal Java'nın Evrimsel Modernizasyonu

Eclipse Foundation liderleri Ivar Grimstad ve Tanja Obradovic'in OCX 2026 oturumlarında ortaya koyduğu "kurumsal Java'yı bozmadan modernize etme" vizyonu; Jakarta EE 12'nin CDI 5.0 merkezli mimarisi, Jakarta Query 1.0 birleşik sorgu katmanı, Jakarta Data 1.1 dinamik kısıtlamaları ve Jakarta Agentic AI entegrasyonu ile derinlemesine inceleniyor.

Emre TaştutanEmre Taştutan
10 dk