Server LLM dapat menerima banyak request pada saat yang sama, tetapi memproses setiap request secara terpisah sering kali merupakan cara yang tidak efisien untuk menggunakan akselerator. GPU dan perangkat keras serupa dirancang untuk menjalankan pekerjaan numerik paralel dalam jumlah besar. Satu request kecil dapat membuat sebagian kapasitas tersebut tidak terpakai.
Batching menggabungkan pekerjaan dari beberapa request agar model dapat memproses lebih banyak pekerjaan secara bersamaan. Ini dapat meningkatkan throughput total, tetapi menghadirkan trade-off penting: menunggu batch terbentuk dapat menunda request individual, dan request dengan panjang sequence berbeda tidak menghabiskan jumlah pekerjaan yang sama.
Bagi developer yang mengoperasikan aplikasi LLM, pertanyaan yang berguna bukan sekadar apakah batching diaktifkan. Pertanyaannya adalah bagaimana sistem serving harus mengelompokkan dan menjadwalkan token sambil memenuhi kebutuhan latensi dan memori.
Pisahkan throughput dan latensi sebagai tujuan
Dua ukuran performa ini mudah tertukar.
Latensi menggambarkan berapa lama sebuah request menunggu output yang berguna. Untuk aplikasi interaktif, time to first token sangat penting karena menentukan seberapa cepat respons tampak mulai diberikan.
Throughput menggambarkan seberapa banyak pekerjaan yang diselesaikan layanan dari waktu ke waktu, misalnya jumlah token yang dihasilkan per detik di seluruh request aktif.
Perubahan pada serving dapat memperbaiki salah satunya sambil memperburuk yang lain. Bayangkan server menerima empat request dengan selang beberapa milidetik:
request A ---->
request B ------>
request C -------->
request D ---------->Memproses masing-masing segera dapat meminimalkan penundaan antrean, tetapi mungkin menggunakan akselerator secara tidak efisien. Menunggu sebentar lalu memprosesnya bersama dapat meningkatkan utilisasi dan throughput, tetapi request A kini harus menunggu batch terbentuk.
Inilah trade-off utama batching.
Mengapa batch dapat menggunakan perangkat keras lebih efisien
Inference Transformer didominasi operasi numerik berskala besar. Akselerator umumnya menjalankan operasi ini dengan lebih efisien ketika tersedia cukup banyak pekerjaan paralel.
Secara konseptual, alih-alih empat eksekusi model terpisah:
[A] -> model
[B] -> model
[C] -> model
[D] -> modelserver dapat menggabungkan pekerjaan yang kompatibel:
[A, B, C, D] -> modelModel tetap harus melakukan komputasi untuk setiap sequence. Batching tidak membuat biaya empat request sama dengan satu request. Manfaatnya berasal dari menjalankan lebih banyak pekerjaan berguna secara bersamaan dan mengamortisasi sebagian overhead eksekusi.
Besarnya manfaat bergantung pada model, perangkat keras, presisi numerik, panjang sequence, serving engine, dan beban saat ini. Menaikkan ukuran batch tanpa batas tidak menjamin peningkatan throughput yang proporsional.
Request LLM bukan pekerjaan dengan ukuran yang sama
Jumlah request merupakan pendekatan yang buruk untuk memperkirakan ukuran workload LLM.
Bandingkan request berikut:
request A: 120 input tokens, 30 output tokens
request B: 4200 input tokens, 200 output tokensKeduanya dihitung sebagai satu request, tetapi kebutuhan komputasi dan memorinya sangat berbeda. Karena itu, sistem serving produksi sering mempertimbangkan token, bukan hanya jumlah request.
Perbedaannya menjadi lebih jelas ketika inference dibagi menjadi dua fase:
- prefill memproses prompt input dan membangun state model yang diperlukan untuk generation;
- decode menghasilkan token baru secara autoregresif, biasanya satu token per sequence aktif pada setiap langkah decoding.
Prompt panjang menghasilkan pekerjaan prefill yang besar. Respons panjang terus memakai kapasitas decode selama banyak langkah. Scheduler yang mengabaikan perbedaan ini dapat menghasilkan latensi buruk meskipun batch request secara nominal terlihat kecil.
Static batching sederhana tetapi kurang cocok untuk traffic interaktif
Strategi batching paling sederhana menunggu sekumpulan request, memproses kelompok tersebut, lalu menyelesaikan batch sebelum menerima kelompok berikutnya.
Pendekatan ini cocok untuk workload offline ketika semua input sudah tersedia:
batch 1: [A, B, C, D] -> finish
batch 2: [E, F, G, H] -> finishContohnya termasuk menghasilkan embedding untuk corpus tetap atau menjalankan evaluasi model pada dataset yang sudah diketahui.
Generation interaktif lebih rumit. Request tiba pada waktu berbeda dan menghasilkan jumlah token berbeda. Jika satu sequence selesai cepat sementara yang lain berlanjut hingga ratusan token, batch yang kaku dapat menyisakan kapasitas tidak terpakai atau membuat request berikutnya menunggu tanpa perlu.
Hal ini mendorong penggunaan penjadwalan dinamis.
Continuous batching mengubah batch saat generation berlangsung
Dengan continuous batching, yang pada beberapa sistem serving juga disebut iteration-level batching, scheduler dapat mengevaluasi ulang pekerjaan aktif di antara iterasi model. Sequence yang selesai keluar, dan sequence yang menunggu dapat masuk ketika kapasitas tersedia.
Timeline sederhananya seperti berikut:
step 1: [A, B, C]
step 2: [A, B, C]
step 3: [A, B] C finishes
step 4: [A, B, D] D joins
step 5: [A, D] B finishesAlgoritma penjadwalan persisnya berbeda antar-inference engine, tetapi model mental ini berguna: batch aktif tidak harus tetap sama sepanjang masa hidup setiap request.
Pendekatan ini dapat meningkatkan utilisasi untuk workload online karena request pendek tidak terus menyisakan slot kosong setelah selesai. Continuous batching juga dapat mengurangi waktu tunggu request baru agar tidak perlu menunggu seluruh batch lama selesai.
Continuous batching adalah strategi serving, bukan perubahan pada perilaku yang dipelajari model. Yang berubah adalah cara pekerjaan inference dijadwalkan di sekitar model.
Panjang sequence menimbulkan biaya padding dan penjadwalan
Ketika sequence dengan panjang berbeda direpresentasikan dalam batch persegi panjang konvensional, sequence yang lebih pendek mungkin memerlukan padding agar dimensi tensor sejajar.
Contoh:
A: [token token token token token]
B: [token token PAD PAD PAD ]
C: [token token token PAD PAD ]Menghitung semua posisi padding secara naif membuang pekerjaan. Inference engine modern dapat menggunakan teknik attention dan manajemen memori khusus untuk mengurangi pemborosan ini, sehingga biaya tepatnya bergantung pada implementasi serving.
Pelajaran yang lebih luas tetap penting: batch berisi sequence dengan ukuran serupa dapat berperilaku berbeda dari batch yang mencampurkan sequence sangat pendek dan sangat panjang.
Saat melakukan benchmark, gunakan distribusi panjang traffic nyata, bukan hanya satu panjang prompt yang nyaman.
Memori membatasi concurrency secara praktis
Semakin banyak request aktif, semakin banyak runtime state yang diperlukan. Selama generation autoregresif, setiap sequence aktif biasanya mempertahankan KV cache yang berisi attention key dan value untuk token yang sudah diproses.
Saat jumlah token aktif bertambah, penggunaan memori KV cache ikut bertambah. Artinya, server tidak dapat meningkatkan concurrency tanpa mempertimbangkan kapasitas memori.
Hubungan operasional yang berguna adalah:
more active requests
+ longer contexts
+ longer generated outputs
= more active token state
= more memory pressureKarena itu, konfigurasi yang mampu menangani banyak percakapan pendek mungkin tidak dapat mempertahankan concurrency yang sama ketika pengguna mengirim dokumen panjang.
Ukuran batch, batas context, dan manajemen memori harus dituning bersama, bukan secara terpisah.
Prefill besar dapat mengganggu decoding interaktif
Bayangkan beberapa pengguna sedang menerima output streaming ketika request lain tiba dengan prompt yang sangat panjang. Memproses prefill prompt tersebut dapat membutuhkan blok komputasi besar.
Jika scheduler memberikan terlalu banyak waktu akselerator tanpa jeda kepada prefill panjang, pengguna yang sudah aktif dapat mengalami pengiriman token yang lebih lambat. Namun, jika scheduler selalu memprioritaskan pekerjaan decode, prompt baru yang besar dapat menunggu terlalu lama sebelum menghasilkan token pertama.
Ini adalah masalah penjadwalan, bukan persoalan satu pengaturan yang selalu benar. Produk yang berbeda dapat memilih kebijakan berbeda:
- antarmuka chat dapat memprioritaskan pengiriman token interaktif yang mulus;
- layanan generation offline dapat memprioritaskan throughput agregat;
- layanan campuran mungkin membutuhkan batas atau antrean terpisah untuk request yang sangat besar.
Sebagian sistem inference dapat membagi atau melakukan chunking pada prefill besar agar dapat berjalan lebih mulus bersama pekerjaan decode. Keberadaan dan perilaku fitur ini bergantung pada implementasi, sehingga perlu dievaluasi pada serving stack yang benar-benar digunakan, bukan diasumsikan.
Penundaan batching harus sepadan dengan biaya latensinya
Server dengan traffic ringan mungkin tidak memiliki cukup request simultan untuk mengisi batch besar. Menunggu lebih lama dapat menghasilkan batch yang lebih penuh, tetapi setiap request yang menunggu membayar latensi antrean tambahan.
Misalkan layanan menggunakan batching window singkat:
request arrives
|
v
wait up to a small window
|
+--> compatible work arrives -> batch together
|
+--> window expires -> run available workWindow yang tepat bergantung pada traffic dan target latensi. Penundaan batch yang tidak berarti bagi background job dapat tidak dapat diterima untuk fitur autocomplete interaktif.
Jangan memilihnya hanya berdasarkan intuisi. Ukur distribusi latensi, terutama persentil tinggi, sambil mengubah kebijakan.
Benchmark dengan bentuk workload yang realistis
Benchmark yang mengirim prompt identik pada concurrency maksimum dapat menunjukkan batas perangkat keras, tetapi tidak selalu memprediksi perilaku produksi.
Pengujian yang lebih representatif setidaknya menggambarkan:
arrival rate
input-token distribution
output-token distribution
concurrent request count
streaming or non-streaming behavior
latency objectiveKemudian catat metrik seperti:
- time to first token;
- inter-token latency atau generation rate;
- latensi request end-to-end;
- throughput total token input dan output;
- waktu antrean;
- utilisasi akselerator;
- penggunaan memori puncak;
- request yang ditolak atau ditunda saat overload.
Perhatikan persentil selain rata-rata. Scheduler dapat menghasilkan rata-rata yang menarik sementara sebagian kecil request panjang atau kurang beruntung mengalami penundaan berat.
Backpressure adalah bagian dari desain batching
Tidak ada strategi batching yang menciptakan kapasitas tanpa batas. Ketika pekerjaan masuk melebihi throughput yang dapat dipertahankan, antrean akan bertambah.
Tanpa kebijakan overload, layanan dapat memasuki kondisi buruk ketika request tetap diterima tetapi menunggu begitu lama hingga aplikasi secara praktis tidak tersedia. Antrean yang lebih besar juga dapat memakai memori host dan memperlambat pemulihan.
Desain produksi harus menentukan apa yang terjadi ketika kapasitas habis. Bergantung pada produk, pilihannya dapat mencakup membatasi concurrency, membatasi ukuran antrean, menolak pekerjaan berlebih, menerapkan kuota per pengguna, atau mengarahkan workload ke pool kapasitas terpisah.
Kebijakan yang tepat bergantung pada produk, tetapi prinsipnya umum: batching meningkatkan cara kapasitas yang tersedia digunakan; batching tidak menggantikan admission control.
Jangan optimalkan throughput secara terpisah
Angka tokens-per-second yang lebih tinggi tidak otomatis menghasilkan pengalaman pengguna yang lebih baik.
Untuk asisten interaktif, konfigurasi yang meningkatkan throughput agregat dengan menunda token pertama secara signifikan dapat menjadi trade-off yang buruk. Untuk batch job malam hari, konfigurasi yang sama mungkin ideal karena latensi request individual tidak relevan.
Demikian pula, memaksimalkan jumlah sequence bersamaan dapat meningkatkan tekanan memori dan membuat latensi kurang dapat diprediksi. Titik operasi terbaik biasanya berada di bawah maksimum teoretis dan bergantung pada service-level objective.
Lakukan tuning berdasarkan metrik yang benar-benar dibutuhkan produk.
Proses tuning yang praktis
Mulailah dengan workload representatif dan konfigurasi serving yang konservatif. Ukur baseline sebelum mengubah batas batch atau perilaku scheduler.
Kemudian ubah satu dimensi pada satu waktu:
- Ukur distribusi panjang token input dan output dari request realistis.
- Tetapkan target latensi dan throughput.
- Tingkatkan concurrency atau batas token-batch secara bertahap.
- Amati throughput, antrean, persentil latensi, dan memori secara bersamaan.
- Uji campuran request pendek dan panjang, bukan hanya input seragam.
- Jalankan pengujian overload untuk memastikan backpressure berperilaku sesuai rancangan.
- Jalankan ulang benchmark ketika model, perangkat keras, presisi, batas context, atau serving engine berubah.
Proses ini menghindari anggapan bahwa nilai batch size dari sistem lain adalah rekomendasi universal.
Kesimpulan
Batching memungkinkan sistem serving LLM menyediakan lebih banyak pekerjaan paralel kepada perangkat keras akselerator sehingga dapat meningkatkan throughput total. Peningkatan ini tidak gratis: menunggu batch terbentuk menambah latensi antrean, sequence aktif mengonsumsi memori, dan panjang prompt serta output yang tidak seragam memperumit penjadwalan.
Untuk workload offline, static batch sederhana mungkin cukup. Untuk generation interaktif, continuous batching dan penjadwalan berbasis token dapat menggunakan kapasitas dengan lebih fleksibel saat request datang dan selesai.
Tujuan praktisnya bukan batch sebesar mungkin. Tujuannya adalah kebijakan penjadwalan yang menjaga perangkat keras tetap mengerjakan pekerjaan berguna sambil memenuhi kebutuhan latensi, memori, dan overload aplikasi. Ukur semua tujuan tersebut bersama traffic yang realistis, karena strategi batching terbaik ditentukan oleh workload, bukan satu nilai batch size universal.