Uji regresi performa untuk model machine learning pada pipeline CI/CD sering kali memicu flaky test akibat Out-Of-Memory (OOM) mendadak atau fluktuasi latensi. Masalah ini semakin kompleks pada akselerator AI generasi baru yang mengadopsi arsitektur monolithic 3D DRAM stacking (seperti konsep Sophon PFG-1). Tanpa bus interkoneksi HBM standar (seperti interposer 2.5D), bandwidth memori vertikal meningkat drastis, namun batas kapasitas fisik tetap fixed dan rentan terhadap fragmentasi saat eksekusi batch panjang.

Tantangan Arsitektur 3D DRAM pada Pipeline CI

Pada arsitektur memori terintegrasi vertikal, komputasi dan memori berada dalam jarak mikroskopis langsung. Karakteristik ini membawa dua konsekuensi utama dalam pengujian perangkat lunak:

  • Sensitivitas Alokasi Non-HBM: Ketiadaan latensi transfer host-to-device tradisional menyamarkan pemborosan memori. Leak kecil pada level buffer C++/runtime langsung mengakibatkan saturasi instan tanpa tanda-tanda bottleneck pada I/O bus.
  • Thermal Throttling Agresif: Karena lapisan DRAM menempel langsung pada silikon logika, peningkatan temperatur saat throughput puncak memicu throttling hardware otomatis. Hal ini menyebabkan variansi eksekusi yang menghasilkan kegagalan tes berbasis batas waktu (timeout).

Strategi Verifikasi Batas Saturasi Memori

Untuk memastikan inferensi stabil di lingkungan CI, runner pengujian harus memverifikasi batas saturasi secara deterministik sebelum artefak dideploy ke produksi.

1. Isolasi Alokasi Memori dan Deteksi Kebocoran

Verifikasi kebocoran memori pada batch berdurasi panjang membutuhkan pemantauan delta alokasi per siklus inferensi. Hindari hanya mengukur memori residu di akhir proses, karena fragmentasi memori internal allocator (seperti PyTorch caching allocator atau jemalloc) dapat menyamarkan leak objek Python dari buffer native.

2. Penanganan Flaky Test Akibat Thermal Throttling

Jangan mengandalkan metrik execution_time < threshold absolut. Gunakan rasio throughput per frekuensi clock aktual atau tetapkan interval cooldown antar skenario stres untuk mencegah fluktuasi hardware mempengaruhi status build CI.

Implementasi Test Harness dengan Pytest

Berikut adalah implementasi minimal test harness menggunakan Python dan pytest untuk memvalidasi batas saturasi memori dan kestabilan inferensi pada batch berkelanjutan:

import gc
import pytest
import torch

class DummyInferenceEngine:
    """Simulasi runtime engine inferensi."""
    def __init__(self, device: str = "cuda"):
        self.device = device
        # Simulasi alokasi bobot model dasar
        self.weights = torch.empty((1024, 1024), device=self.device, dtype=torch.float32)

    def infer(self, batch: torch.Tensor) -> torch.Tensor:
        # Simulasi komputasi inferensi
        return torch.matmul(batch, self.weights)

@pytest.fixture
def engine():
    dev = "cuda" if torch.cuda.is_available() else "cpu"
    inst = DummyInferenceEngine(device=dev)
    yield inst
    del inst
    gc.collect()
    if torch.cuda.is_available():
        torch.cuda.empty_cache()

def test_memory_saturation_threshold(engine):
    """Verifikasi konsumsi memori stabil selama batch panjang tanpa OOM."""
    batch_size = 256
    seq_len = 1024
    iterations = 50
    
    device = engine.device
    if device == "cpu":
        pytest.skip("Pengujian saturasi memori memerlukan akselerator target")

    # Catat memori awal setelah pemuatan model
    torch.cuda.reset_peak_memory_stats(device)
    baseline_mem = torch.cuda.memory_allocated(device)

    # Jalankan inferensi berulang untuk simulasi beban kerja kontinu
    for _ in range(iterations):
        inputs = torch.randn((batch_size, seq_len), device=device, dtype=torch.float32)
        outputs = engine.infer(inputs)
        assert outputs.shape == (batch_size, seq_len)
        del inputs, outputs

    # Evaluasi penggunaan memori akhir
    gc.collect()
    final_mem = torch.cuda.memory_allocated(device)
    peak_mem = torch.cuda.max_memory_allocated(device)

    # Validasi batas toleransi kebocoran (delta harus 0 atau di bawah ambang batas alokator)
    memory_leak_bytes = final_mem - baseline_mem
    assert memory_leak_bytes == 0, f"Kebocoran memori terdeteksi: {memory_leak_bytes} bytes"

    # Validasi bahwa peak tidak melampaui 85% kapasitas memori yang tersedia
    total_mem = torch.cuda.get_device_properties(device).total_memory
    saturation_ratio = peak_mem / total_mem
    assert saturation_ratio < 0.85, f"Saturasi memori mendekati batas kritis: {saturation_ratio:.2%}"

Konfigurasi Pipeline CI

Untuk menjalankan pengujian ini secara stabil pada CI runner (misalnya GitHub Actions atau GitLab CI dengan self-hosted hardware runner):

  1. Nonaktifkan Dynamic Frequency Scaling: Kunci frekuensi GPU/akselerator pada level tetap menggunakan perintah hardware control tool vendor untuk meniadakan variasi performa akibat temperatur.
  2. Jalankan Test Secara Serial: Hindari menjalankan test model paralel via pytest-xdist pada kartu akselerator yang sama untuk mencegah perebutan ruang alamat memori fisik.
  3. Tangani Sinyal OOM: Konfigurasikan runner agar menangkap exit code 137 (SIGKILL) dan mengekspor log status memori sebelum proses dihentikan oleh kernel OS.