<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Development on kenji.blog</title><link>http://kenji.blog/id/tags/development/</link><description>Recent content in Development on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>id</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 14:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/id/tags/development/index.xml" rel="self" type="application/rss+xml"/><item><title>Panduan Pengembangan Model AI Skala Kecil (seperti TinyLLaMA) Menggunakan C++</title><link>http://kenji.blog/id/p/cpp-small-ai-model-tinyllama-dev-guide/</link><pubDate>Fri, 11 Sep 2026 14:00:00 +0900</pubDate><guid>http://kenji.blog/id/p/cpp-small-ai-model-tinyllama-dev-guide/</guid><description>&lt;img src="http://kenji.blog/p/cpp-small-ai-model-tinyllama-dev-guide/img/eyecatch.jpg" alt="Featured image of post Panduan Pengembangan Model AI Skala Kecil (seperti TinyLLaMA) Menggunakan C++" />&lt;h1 id="panduan-pengembangan-model-ai-skala-kecil-seperti-tinyllama-menggunakan-c">Panduan Pengembangan Model AI Skala Kecil (seperti TinyLLaMA) Menggunakan C++
&lt;/h1>&lt;p>Baru-baru ini, minat terhadap eksekusi model bahasa besar (LLM) di lingkungan lokal telah meningkat secara pesat. Secara khusus, model berskala kecil seperti TinyLLaMA (1.1B parameter) dapat diinferensi dengan kecepatan praktis bahkan pada perangkat edge dengan sumber daya terbatas atau laptop umum (termasuk lingkungan Windows). Sementara pengembangan menggunakan Python dan PyTorch adalah arus utama, ketika mengejar kinerja dan efisiensi memori terbaik, kombinasi C++ dan pustaka tensor berbasis C, &amp;ldquo;ggml&amp;rdquo;, telah menjadi standar de facto.&lt;/p>
&lt;p>Artikel ini akan menjelaskan secara rinci prosedur pengembangan (atau pemahaman mendalam tentang struktur internal llama.cpp yang sudah ada) untuk membangun mesin inferensi dari awal guna memuat TinyLLaMA dan melakukan pembuatan teks menggunakan C++.&lt;/p>
&lt;hr>
&lt;h2 id="1-mengapa-c-dan-ggml">1. Mengapa C++ dan ggml?
&lt;/h2>&lt;p>Dalam tahap pelatihan AI, Python sangat diuntungkan dengan fleksibilitas dan ekosistemnya yang kaya. Namun, dalam fase penerapan dan &amp;ldquo;Inferensi&amp;rdquo;, C++ menjadi pilihan yang kuat karena alasan berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Pengurangan Overhead&lt;/strong>: Global Interpreter Lock (GIL) Python dan overhead runtime dapat dihilangkan sepenuhnya.&lt;/li>
&lt;li>&lt;strong>Efisiensi Memori dan Alokasi Arena&lt;/strong>: Karena alokasi dan dealokasi memori dapat dikontrol secara manual, lonjakan yang tidak dapat diprediksi akibat &lt;em>garbage collection&lt;/em> dapat dicegah.&lt;/li>
&lt;li>&lt;strong>Akses Langsung ke Perangkat Keras&lt;/strong>: Dapat langsung memanggil fungsi bawaan SIMD (Intrinsics) seperti AVX-512, AVX2, dan ARM NEON untuk memaksimalkan kemampuan komputasi CPU.&lt;/li>
&lt;li>&lt;strong>Tanpa Dependensi&lt;/strong>: ggml adalah pustaka C/C++ dengan nol dependensi (Zero dependencies), yang dapat dengan mudah dibangun bahkan di lingkungan MSVC di Windows asalkan ada kompilator.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="2-gambaran-keseluruhan-arsitektur">2. Gambaran Keseluruhan Arsitektur
&lt;/h2>&lt;p>Alur dari seluruh &lt;em>pipeline&lt;/em> inferensi ditunjukkan dalam diagram Mermaid di bawah ini. Ini adalah serangkaian proses mulai dari teks masukan pengguna hingga pembuatan token berikutnya.&lt;/p>
&lt;div class="mermaid">graph TD
A["Teks Masukan Pengguna"] --> B["BPE Tokenizer"]
B --> C["Array ID Token"]
C --> D["Pencarian Lapisan Embedding"]
D --> E["Blok Transformer"]
E --> F["RMSNorm"]
F --> G["Lapisan LM Head"]
G --> H["Array Logit"]
H --> I["Modul Sampler"]
I --> J["ID Token Berikutnya"]
J --> K["Detokenizer"]
K --> L["Potongan Teks Keluaran"]
J -.-> |"Tambahkan ke Konteks"| C&lt;/div>
&lt;p>Karena ini adalah model auto-regresif, token yang dihasilkan ditambahkan kembali ke konteks dan disirkulasikan sebagai masukan untuk memprediksi token berikutnya (bagian garis putus-putus pada diagram).&lt;/p>
&lt;hr>
&lt;h2 id="3-format-model-dan-pemetaan-memori-mmap">3. Format Model dan Pemetaan Memori (mmap)
&lt;/h2>&lt;p>Kendala terbesar dalam menangani bobot jaringan saraf yang sangat besar adalah operasi I/O disk dan konsumsi memori. Implementasi C++ menyelesaikan masalah ini dengan &lt;strong>pemetaan memori (mmap)&lt;/strong>.&lt;/p>
&lt;h3 id="31-cara-kerja-pemetaan-memori-dan-implementasi-di-windows">3.1 Cara Kerja Pemetaan Memori dan Implementasi di Windows
&lt;/h3>&lt;p>Menggunakan mmap memungkinkan konten file dipetakan langsung ke dalam ruang memori virtual proses.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Zero-copy (Tanpa Salinan)&lt;/strong>: Data dibaca langsung dari disk ke dalam tembolok halaman kernel, dan tidak ada salinan ekstra ke ruang pengguna yang terjadi.&lt;/li>
&lt;li>&lt;strong>On-demand Load (Page Fault)&lt;/strong>: Tepat saat CPU mengakses alamat memori tersebut, &lt;em>page fault&lt;/em> terjadi, dan hanya &lt;em>chunk&lt;/em> yang diperlukan (biasanya 4KB) yang dimuat ke dalam memori fisik.&lt;/li>
&lt;/ul>
&lt;p>Di lingkungan Windows, API Win32 &lt;code>CreateFileMapping&lt;/code> dan &lt;code>MapViewOfFile&lt;/code> digunakan sebagai pengganti POSIX &lt;code>mmap&lt;/code>.&lt;/p>
&lt;div class="mermaid">sequenceDiagram
participant OS["OS Windows"]
participant RAM["Memori Fisik"]
participant App["Aplikasi C++"]
App->>OS: "CreateFileMapping / MapViewOfFile"
OS-->>App: "Penunjuk Alamat Memori Virtual"
App->>App: "Baca Data Tensor pada Penunjuk"
OS->>RAM: "Page Fault / Muat halaman dari Disk"
RAM-->>App: "Data siap untuk Komputasi SIMD"&lt;/div>
&lt;h3 id="32-struktur-biner-format-gguf">3.2 Struktur Biner Format GGUF
&lt;/h3>&lt;p>&lt;strong>GGUF (GPT-Generated Unified Format)&lt;/strong>, yang dikonversi dari format seperti &lt;code>.safetensors&lt;/code> Hugging Face, adalah format pamungkas untuk inferensi. GGUF memiliki tata letak biner ketat berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Magic Bytes&lt;/strong>: &lt;code>0x46554747&lt;/code> (GGUF).&lt;/li>
&lt;li>&lt;strong>Version&lt;/strong>: Nomor versi format.&lt;/li>
&lt;li>&lt;strong>Tensor Count &amp;amp; Metadata Count&lt;/strong>: Jumlah tensor dan jumlah pasangan kunci-nilai metadata.&lt;/li>
&lt;li>&lt;strong>Metadata (Key-Value Pairs)&lt;/strong>: Kunci dengan prefiks panjang string, dan nilai yang diketik.&lt;/li>
&lt;li>&lt;strong>Tensor Info&lt;/strong>: Nama setiap tensor, jumlah dimensi, tipe data (FP16, Q4_K, dll.), dan posisi &lt;em>offset&lt;/em> di dalam file.&lt;/li>
&lt;li>&lt;strong>Padding&lt;/strong>: Padding yang dimasukkan agar data tensor sejajar (aligned) pada batas tertentu (biasanya 32 byte atau 64 byte). Ini penting untuk akses memori cepat dalam instruksi SIMD (khususnya AVX).&lt;/li>
&lt;li>&lt;strong>Tensor Data&lt;/strong>: Array data bobot aktual yang telah disejajarkan.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="4-basis-matematis-tinyllama-dan-algoritma-c">4. Basis Matematis TinyLLaMA dan Algoritma C++
&lt;/h2>&lt;p>TinyLLaMA menggabungkan beberapa penyempurnaan arsitektur tingkat lanjut untuk efisiensi. Ekspresi matematis untuk mengimplementasikan ini dengan benar dalam C++ dijelaskan di bawah ini.&lt;/p>
&lt;h3 id="41-rmsnorm-root-mean-square-normalization">4.1 RMSNorm (Root Mean Square Normalization)
&lt;/h3>&lt;p>Ini mengurangi biaya komputasi dengan menghilangkan pemusatan rata-rata dari LayerNorm dan hanya melakukan penskalaan varians.&lt;/p>
$$ \text{RMSNorm}(x) = \frac{x}{\sqrt{\frac{1}{d}\sum_{i=1}^{d} x_i^2 + \epsilon}} \odot \gamma $$
&lt;p>$d$ adalah jumlah dimensi, dan $\gamma$ adalah tensor penskalaan yang telah dipelajari.
Saat diimplementasikan di C++, ini dioptimalkan dengan terlebih dahulu menghitung jumlah kuadrat array pada kecepatan tinggi menggunakan &lt;code>_mm256_fmadd_ps&lt;/code> dari AVX2, dll., dan mengalikannya dengan akar kuadrat terbalik (seperti instruksi &lt;code>_mm256_rsqrt_ps&lt;/code>).&lt;/p>
&lt;h3 id="42-rope-rotary-position-embedding">4.2 RoPE (Rotary Position Embedding)
&lt;/h3>&lt;p>Ini adalah teknik yang menerapkan informasi posisi token sebagai rotasi (Rotate) di ruang tensor. Ini dapat dianggap sebagai rotasi pada bidang kompleks, dan rotasi berikut diterapkan ke pasangan dimensi yang berdekatan $(x_1, x_2)$ dari vektor $x$.&lt;/p>
$$ \text{RoPE}(x, m) = \begin{pmatrix} x_{1} \cos(m\theta) - x_{2} \sin(m\theta) \\ x_{1} \sin(m\theta) + x_{2} \cos(m\theta) \end{pmatrix} $$
&lt;p>Di sini, $m$ adalah indeks posisi absolut token, dan $\theta$ adalah frekuensi dasar yang dihitung sebelumnya. Dalam ggml, eksekusi paralel dapat dicapai hanya dengan menambahkan operator &lt;code>ggml_rope&lt;/code> selama pembangunan grafik inferensi.&lt;/p>
&lt;h3 id="43-grouped-query-attention-gqa">4.3 Grouped-Query Attention (GQA)
&lt;/h3>&lt;p>Dalam Multi-Head Attention (MHA) reguler, terdapat jumlah head yang sama untuk masing-masing Query, Key, dan Value. Namun, TinyLLaMA mengadopsi &lt;strong>Grouped-Query Attention (GQA)&lt;/strong> untuk secara drastis mengurangi &lt;em>bandwidth&lt;/em> memori dan konsumsi tembolok KV (KV Cache).&lt;/p>
$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q K^T}{\sqrt{d_k}}\right) V $$
&lt;p>Di GQA, beberapa head Query berbagi satu head Key/Value. Dalam implementasi C++, perlu melakukan operasi &lt;em>broadcast&lt;/em> pada tensor KV agar sesuai dengan jumlah Query sebelum menjalankan perkalian matriks &lt;code>ggml_mul_mat&lt;/code>.&lt;/p>
&lt;h3 id="44-fungsi-aktivasi-swiglu">4.4 Fungsi Aktivasi SwiGLU
&lt;/h3>&lt;p>Pada lapisan Feed-Forward Network (FFN), SwiGLU digunakan sebagai pengganti GELU.&lt;/p>
$$ \text{SwiGLU}(x) = \text{Swish}(x W_{\text{gate}}) \otimes (x W_{\text{up}}) $$
$$ \text{Swish}(z) = z \cdot \sigma(z) = z \cdot \frac{1}{1 + e^{-z}} $$
&lt;p>Dalam grafik komputasi, ini diekspresikan dengan menggabungkan operator &lt;code>ggml_silu&lt;/code> dan &lt;code>ggml_mul&lt;/code>.&lt;/p>
&lt;hr>
&lt;h2 id="5-pembangunan-grafik-komputasi-dan-manajemen-memori-dengan-ggml">5. Pembangunan Grafik Komputasi dan Manajemen Memori dengan ggml
&lt;/h2>&lt;p>ggml mengambil pendekatan &amp;ldquo;Define-and-Run&amp;rdquo;, di mana grafik komputasi statis untuk inferensi dibangun dan dievaluasi nanti.&lt;/p>
&lt;h3 id="51-ggml_context-dan-arena-allocator">5.1 ggml_context dan Arena Allocator
&lt;/h3>&lt;p>Fitur ggml yang paling unik adalah &amp;ldquo;alokasi arena&amp;rdquo;, yang sama sekali tidak menggunakan alokasi memori dinamis (&lt;code>malloc&lt;/code> atau &lt;code>new&lt;/code>) dalam putaran inferensi.
Area memori (&lt;em>arena&lt;/em>) bersebelahan yang besar dialokasikan saat inisialisasi, dan penunjuk area ini dinaikkan nilainya (incremented) setiap kali &lt;code>ggml_new_tensor&lt;/code> dll. dipanggil. Ketika satu langkah inferensi selesai, hanya dengan mengatur ulang penunjuk alokasi ke posisi awalnya, alokasi memori untuk langkah inferensi berikutnya selesai secara instan.&lt;/p>
&lt;h3 id="52-contoh-konkret-pembangunan-grafik">5.2 Contoh Konkret Pembangunan Grafik
&lt;/h3>&lt;p>Untuk setiap langkah inferensi, grafik komputasi berikut dirakit dalam memori.&lt;/p>
&lt;div class="mermaid">graph TD
A["ID Masukan Token"] --> B["Pencarian Embed"]
B --> C["ggml_rms_norm"]
C --> D["Proyeksi Q / K / V"]
D --> E["Posisi ggml_rope"]
E --> F["Simpan Tembolok KV"]
E --> G["Muat Tembolok KV"]
G --> H["Self Attention"]
H --> I["Skala &amp; Softmax"]
I --> J["Keluaran Attention"]
J --> K["Proyeksi Keluar"]
K --> L["Tambah Residual"]&lt;/div>
&lt;hr>
&lt;h2 id="6-kuantisasi-quantization-dan-optimisasi-windows--simd">6. Kuantisasi (Quantization) dan Optimisasi Windows / SIMD
&lt;/h2>&lt;p>Jika Anda menangani TinyLLaMA (1.1B) dalam FP16, Anda membutuhkan sekitar 2,2GB memori, tetapi melalui kuantisasi 4-bit (seperti Q4_K), ini dapat dikompresi secara dramatis menjadi sekitar 600MB.&lt;/p>
&lt;h3 id="61-arsitektur-kuantisasi-blok">6.1 Arsitektur Kuantisasi Blok
&lt;/h3>&lt;p>ggml tidak mengkuantisasi seluruh tensor secara seragam, melainkan dalam satuan &amp;ldquo;blok&amp;rdquo;.
Dalam format &lt;code>Q4_0&lt;/code>, 32 nilai FP16 dikelompokkan ke dalam satu blok.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Faktor Skala&lt;/strong>: Satu nilai FP16 (2 byte)&lt;/li>
&lt;li>&lt;strong>Data Terkuantisasi&lt;/strong>: 32 nilai 4-bit (16 byte)
Ini meminimalkan dampak dari &lt;em>outlier&lt;/em> lokal.&lt;/li>
&lt;/ul>
&lt;h3 id="62-akselerasi-produk-titik-dengan-avx2">6.2 Akselerasi Produk Titik dengan AVX2
&lt;/h3>&lt;p>Saat membangun untuk CPU x86 terbaru di lingkungan Windows, pemrosesan SIMD dilakukan dalam alur berikut, memanfaatkan tanda (flag) kompilator seperti &lt;code>/arch:AVX2&lt;/code>.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Muat&lt;/strong>: Muat data terkuantisasi 4-bit dari memori ke dalam register AVX 256-bit.&lt;/li>
&lt;li>&lt;strong>Ekspansi dan Buka Paket&lt;/strong>: Ekspansi nilai 4-bit menjadi Int8 atau Int16 dengan &lt;em>bit mask&lt;/em> dan operasi pergeseran (&lt;em>shift&lt;/em>).&lt;/li>
&lt;li>&lt;strong>Dikuantisasi Balik (Dequantization)&lt;/strong>: Kalikan faktor skala untuk mengonversi ke angka &lt;em>floating-point&lt;/em>.&lt;/li>
&lt;li>&lt;strong>Operasi FMA&lt;/strong>: Jalankan operasi perkalian-penjumlahan secara paralel dengan nilai aktivasi dan &lt;code>_mm256_fmadd_ps&lt;/code> (Fused Multiply-Add).&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="7-detail-implementasi-tembolok-kv-kv-cache">7. Detail Implementasi Tembolok KV (KV Cache)
&lt;/h2>&lt;p>Dalam generasi auto-regresif, &amp;ldquo;Tembolok KV&amp;rdquo; (KV Cache) adalah fitur penting untuk mengabaikan penghitungan Key dan Value dari token masa lalu.&lt;/p>
&lt;p>Poin-poin penting saat menerapkan dalam C++ adalah sebagai berikut:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Prapengalokasian Tensor&lt;/strong>: Inisialisasi tensor yang sangat besar untuk ukuran konteks maksimum (misalnya: 2048 token) untuk tembolok KV (FP16 disarankan).&lt;/li>
&lt;li>&lt;strong>Salinan Offset&lt;/strong>: Saat komputasi dilakukan untuk posisi token $N$, simpan vektor K dan V yang diperoleh pada langkah tersebut di baris ke-$N$ dari tensor tembolok KV menggunakan &lt;code>ggml_cpy&lt;/code> atau sejenisnya.&lt;/li>
&lt;li>&lt;strong>Pembuatan Tampilan Saat Attention&lt;/strong>: Saat menghitung Attention, buat &amp;ldquo;tampilan&amp;rdquo; (view) yang hanya menunjuk ke bagian dari token ke-0 hingga ke-$N$ dan teruskan ke perkalian matriks.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="8-bpe-tokenizer-dan-decoding">8. BPE Tokenizer dan Decoding
&lt;/h2>&lt;p>String masukan diperlakukan sebagai urutan byte UTF-8 dan dicocokkan dengan kosakata yang telah ditentukan sebelumnya. Di C++, algoritma menggunakan &lt;strong>Pohon Trie (Pohon Prefiks)&lt;/strong> atau antrean prioritas (priority queue) diimplementasikan untuk mempercepat pencarian kosakata.&lt;/p>
&lt;p>Dari logit yang dikeluarkan dari LM Head, probabilitas diskalakan menggunakan parameter Temperature, kandidat dipersempit dengan metode ekstraksi Top-K atau Top-P (Nucleus Sampling), dan token berikutnya pada akhirnya ditentukan menggunakan angka acak.&lt;/p>
&lt;hr>
&lt;h2 id="9-mempersiapkan-proyek-c-lingkungan-windows--powershell">9. Mempersiapkan Proyek C++ (Lingkungan Windows / PowerShell)
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.14&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">TinyLLaMACpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">17&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># Pengaturan Optimisasi dan bendera AVX2 untuk Windows (MSVC)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MSVC&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/O2&lt;/span> &lt;span class="s">/arch:AVX2&lt;/span> &lt;span class="s">/fp:fast&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_link_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">/STACK:8388608&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">else&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">add_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">-O3&lt;/span> &lt;span class="s">-march=native&lt;/span> &lt;span class="s">-ffast-math&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">OBJECT&lt;/span> &lt;span class="s">ggml/ggml.c&lt;/span> &lt;span class="s">ggml/ggml-alloc.c&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_compile_definitions&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ggml&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">GGML_USE_AVX2&lt;/span> &lt;span class="s">GGML_USE_F16C&lt;/span> &lt;span class="s">GGML_USE_FMA&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">main&lt;/span> &lt;span class="s">ggml&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Contoh perintah pembuatan (build) di PowerShell:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-powershell" data-lang="powershell">&lt;span class="line">&lt;span class="cl">&lt;span class="n">mkdir&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd &lt;/span>&lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">..&lt;/span> &lt;span class="n">-G&lt;/span> &lt;span class="s2">&amp;#34;Visual Studio 17 2022&amp;#34;&lt;/span> &lt;span class="n">-A&lt;/span> &lt;span class="n">x64&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cmake&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-build&lt;/span> &lt;span class="p">.&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="n">-config&lt;/span> &lt;span class="n">Release&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="10-kesimpulan">10. Kesimpulan
&lt;/h2>&lt;p>Membangun mesin inferensi dari awal untuk model AI berskala kecil seperti TinyLLaMA menggunakan C++ dan ggml adalah kesempatan bagus untuk mengungkap kotak hitam (&lt;em>black box&lt;/em>) pembelajaran mendalam dan mempelajari keindahan kontrol perangkat keras tingkat rendah. Mari kita membuka masa depan Edge AI sambil menikmati sepenuhnya esensi pemrograman sistem, seperti pemuatan &lt;em>zero-copy&lt;/em> menggunakan pemetaan memori, optimisasi SIMD, dan pembangunan tembolok KV.&lt;/p></description></item></channel></rss>