<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>ataadevs — blog</title>
    <link>https://ataadevs.net/blog.html</link>
    <description>Ataa Aldaghstani is a full-stack &amp; AI engineer based in Türkiye. Personal site and blog about software engineering, LLMs, and building things.</description>
    <language>en</language>
    <lastBuildDate>Mon, 24 Aug 2026 21:00:00 GMT</lastBuildDate>
    <generator>vite blog plugin</generator>
    <item>
      <title>Building llama.cpp with ROCm 7.14 on Ubuntu — A Source Build</title>
      <link>https://ataadevs.net/blog/building-llamacpp-rocm-ubuntu.html</link>
      <guid isPermaLink="true">https://ataadevs.net/blog/building-llamacpp-rocm-ubuntu.html</guid>
      <pubDate>Mon, 24 Aug 2026 21:00:00 GMT</pubDate>
      <description>A clear step-by-step guide to building llama.cpp from source with ROCm on Ubuntu — installing the dev packages, the exact CMake flags for gfx1201, and a runtime environment that just works.</description>
      <content:encoded><![CDATA[<!-- Overview -->
              <p>
                llama.cpp runs GGUF models directly on your AMD GPU when built against ROCm. On Linux you often want a source build so you can match your exact GPUs and rebuild on a whim. This guide walks through the whole thing in order, from installing the ROCm pieces CMake needs to running a model across multiple GPUs.
              </p>
              <p>
                <strong>The setup I'm using.</strong> An AMD Ryzen 7 7800X3D CPU with two discrete Radeons — an RX 9070 XT (16 GB) and an AI PRO R9700 (32 GB), both RDNA 4 (<code>gfx1201</code>) — plus the CPU's integrated graphics (<code>gfx1036</code>). Two architectures on one machine, which step 6 addresses.
              </p>

              <!-- Step 1 -->
              <h2>Step 1: Install ROCm</h2>
              <p>
                Install ROCm with the <code>amdgpu-install</code> script, selecting ROCm plus graphics:
              </p>
              <pre><code>sudo amdgpu-install --usecase=rocm,graphics</code></pre>
              <p>
                Reboot afterwards, then confirm your GPUs are visible:
              </p>
              <pre><code>rocminfo</code></pre>

              <!-- Step 2 -->
              <h2>Step 2: Install the ROCm Development Packages</h2>
              <p>
                Building from source needs the development packages, which ship the CMake config files that llama.cpp's configure step requires (<code>hip-config.cmake</code>, <code>hipblas-config.cmake</code>, <code>rocblas-config.cmake</code>). They are separate from the runtime install. On ROCm 7.14's packaging install them with:
              </p>
              <pre><code>sudo apt install \
    amdrocm-runtime-dev7.14 \
    amdrocm-blas-dev7.14 \
    amdrocm-core-dev7.14-gfx1201 \
    amdrocm-hipblas-common-dev7.14</code></pre>
              <p>
                A note on the packages:
              </p>
              <ul>
                <li><code>amdrocm-runtime-dev7.14</code> — the HIP runtime development files, including <code>hip-config.cmake</code> and the <code>hip-lang</code> package.</li>
                <li><code>amdrocm-blas-dev7.14</code> — the hipBLAS and rocBLAS dev files that provide the BLAS CMake configs.</li>
                <li><code>amdrocm-core-dev7.14-gfx1201</code> — architecture-specific core dev files; pick the target that matches your GPU.</li>
                <li><code>amdrocm-hipblas-common-dev7.14</code> — shared header-only hipBLAS files.</li>
              </ul>
              <p>
                To double-check the CMake files are present before configuring, run:
              </p>
              <pre><code>find /opt/rocm -name "hip-config.cmake" -o -name "hipblas-config.cmake" -o -name "rocblas-config.cmake"</code></pre>

              <!-- Step 3 -->
              <h2>Step 3: Configure with CMake</h2>
              <p>
                Now configure the build. Because HIP code must be compiled by ROCm's bundled clang — not the system gcc — set both compilers explicitly. Pass <code>GPU_TARGETS=gfx1201</code> to build kernels for your discrete RDNA 4 GPUs.
              </p>
              <pre><code>cmake -S . -B build \
  -DGGML_HIP=ON \
  -DGPU_TARGETS=gfx1201 \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_C_COMPILER=/opt/rocm/llvm/bin/clang \
  -DCMAKE_CXX_COMPILER=/opt/rocm/llvm/bin/clang++</code></pre>
              <p>
                If you want one binary that also runs on the integrated GPU, add it as a second target:
              </p>
              <pre><code>  -DGPU_TARGETS="gfx1201;gfx1036"</code></pre>
              <p>
                That costs a longer build and a bigger binary. I built only for <code>gfx1201</code> and hid the iGPU at runtime instead (step 7).
              </p>

              <!-- Step 4 -->
              <h2>Step 4: Build</h2>
              <p>
                With configure done, build — everything in parallel:
              </p>
              <pre><code>cmake --build build --config Release -j$(nproc)</code></pre>
              <p>
                This compiles the HIP kernels under <code>ggml/src/ggml-hip</code> for each target. On an 8-core 7800X3D it takes a while; it finishes on its own. The <code>llama-cli</code>, <code>llama-server</code>, and <code>llama-bench</code> binaries end up in <code>build/bin</code>.
              </p>

              <!-- Step 5 -->
              <h2>Step 5: Set the Runtime Library Path</h2>
              <p>
                On this ROCm release the runtime libraries live under <code>/opt/rocm/core-7.14/lib</code> — a path the system loader doesn't know about by default. Point it there so the binaries can find their dependencies:
              </p>
              <pre><code>export LD_LIBRARY_PATH=/opt/rocm/core-7.14/lib:$LD_LIBRARY_PATH</code></pre>
              <p>
                Confirm everything resolves by checking your binary against the dynamic libraries:
              </p>
              <pre><code>ldd build/bin/llama-cli</code></pre>
              <p>
                Every <code>libhipblas</code>, <code>librocblas</code>, and <code>libamdhip64</code> should resolve to a real path — none should read "not found".
              </p>

              <!-- Step 6 -->
              <h2>Step 6: Verify the GPUs</h2>
              <p>
                llama.cpp reports what it sees:
              </p>
              <pre><code>./build/bin/llama-cli --list-devices
Available devices:
  ROCm0: AMD Radeon RX 9070 XT   (16304 MiB)
  ROCm1: AMD Radeon AI PRO R9700 (32624 MiB)
  ROCm2: AMD Radeon Graphics     (14953 MiB)</code></pre>

              <!-- Step 7 -->
              <h2>Step 7: Exclude the Integrated GPU</h2>
              <p>
                The third entry is the CPU's integrated graphics. The discrete cards are <code>gfx1201</code>; the iGPU is <code>gfx1036</code> — a different architecture with no matching kernels in this build. Keeping it out of the process entirely is simplest; it also avoids the classic multiple-architecture conflict on machines with both an iGPU and a discrete AMD GPU. Hide it from HIP:
              </p>
              <pre><code>export HIP_VISIBLE_DEVICES=0,1</code></pre>
              <p>
                Now device list shows only the two discrete cards:
              </p>
              <pre><code>./build/bin/llama-cli --list-devices
ROCm0: AMD Radeon RX 9070 XT
ROCm1: AMD Radeon AI PRO R9700</code></pre>

              <!-- Step 8 -->
              <h2>Step 8: Set Up ~/.bashrc</h2>
              <p>
                Exporting those two variables each session gets tiring. Add them to <code>~/.bashrc</code> so every new terminal is ready to go:
              </p>
              <pre><code># llama.cpp + ROCm 7.14 environment
export LD_LIBRARY_PATH=/opt/rocm/core-7.14/lib:$LD_LIBRARY_PATH
export HIP_VISIBLE_DEVICES=0,1

# handy aliases
alias llama-cli='$HOME/source/repos/llama.cpp/build/bin/llama-cli'
alias llama-server='$HOME/source/repos/llama.cpp/build/bin/llama-server'
alias llama-bench='$HOME/source/repos/llama.cpp/build/bin/llama-bench'</code></pre>
              <p>
                Open a fresh terminal and everything is there.
              </p>

              <!-- Step 9 -->
              <h2>Step 9: Run a Model</h2>
              <p>
                Run with a local GGUF model, using <code>-ngl 99</code> to push every layer to the GPU:
              </p>
              <pre><code>llama-cli -m path/to/model.gguf -ngl 99 -p "Hello" --no-display-prompt</code></pre>
              <p>
                To use both discrete cards together, layer split is the simplest reliable option:
              </p>
              <pre><code>llama-cli -m path/to/model.gguf -ngl 99 -sm layer</code></pre>
              <p>
                For tensor split with good throughput, rebuild with <code>-DGGML_HIP_RCCL=ON</code> so the two GPUs can communicate directly instead of through system memory.
              </p>

              <!-- Wrap up -->
              <h2>Wrapping Up</h2>
              <p>
                From a fresh install to a running multi-GPU llama.cpp, it's these eight commands' worth of steps:
              </p>
              <ul>
                <li>Install ROCm, then the development packages.</li>
                <li>Configure with ROCm's clang and <code>GPU_TARGETS=gfx1201</code>.</li>
                <li>Build, and export <code>LD_LIBRARY_PATH</code> to the ROCm lib dir.</li>
                <li>Hide the integrated GPU with <code>HIP_VISIBLE_DEVICES</code>.</li>
                <li>Pin it all in <code>~/.bashrc</code> so a fresh terminal is ready immediately.</li>
              </ul>
              <p>
                Once it's set up it just runs. I'll keep posting about squeezing tokens out of these Radeon cards.
              </p>]]></content:encoded>
    </item>
    <item>
      <title>Squeezing Qwen 3.8 27B into a Single 16 GB GPU — Almost 42 tok/s, 64K Context</title>
      <link>https://ataadevs.net/blog/qwen-3-8-27b-llamacpp-benchmarks.html</link>
      <guid isPermaLink="true">https://ataadevs.net/blog/qwen-3-8-27b-llamacpp-benchmarks.html</guid>
      <pubDate>Sun, 16 Aug 2026 21:00:00 GMT</pubDate>
      <description>How I squeezed the new Qwen 3.8 27B completely onto a single 16 GB GPU — and what it takes to get almost 42 tok/s with a 64K-token KV cache. Two quantizations, four llama.cpp configurations, full commands and results.</description>
      <content:encoded><![CDATA[<!-- Introduction -->
              <p>
                In my previous post, <a href="/blog/run-qwen-3-8-27b-windows-rocm.html">Run Qwen 3.8 27B on Windows with ROCm</a>, I set up Qwen 3.8 27B on an AMD GPU — building llama.cpp from source for maximum throughput. The setup works. The question this post answers is a different one: <strong>which quantization, and which server flags, should you actually run?</strong>
              </p>
              <p>
                I benchmarked two 27B quantizations — <strong>unsloth's Q4_K_M</strong> and <strong>AtomicChat's AD-IQ4_XS-IQ3_S</strong> — each in two configurations: <strong>with MTP2</strong> (multi-token-prediction drafting, n=2) and <strong>without MTP</strong>. Four configurations total, all on the same 16 GB card, all driven through the same real coding task.
              </p>

              <!-- Test setup -->
              <h2>Test setup</h2>
              <ul>
                <li><strong>GPU:</strong> AMD Radeon RX 9070 XT, 16 GB VRAM — dedicated to AI (a separate GPU handles display)</li>
                <li><strong>CPU:</strong> AMD Ryzen 7 7800X3D</li>
                <li><strong>RAM:</strong> DDR5</li>
                <li><strong>Runtime:</strong> llama.cpp built from source with the ROCm backend (per the setup post), all layers offloaded to the GPU (<code>-ngl 99</code>)</li>
              </ul>
              <p>
                <strong>The workload.</strong> Every configuration ran the same real task: a coding agent (the pi harness) pointed at a simple Vite.js repository — my profile website — with the prompt <em>"explain this repo to me (all files)"</em>. That's a realistic, context-heavy workload: it reads a lot of files, holds them in context, and produces a long structured explanation.
              </p>
              <p>
                <strong>One observation before the results:</strong> in all four configurations, the llama-server process accounted for around <strong>13 GB of DDR5 system RAM</strong> — that's its <strong>mmap</strong>. llama.cpp memory-maps the GGUF file, so the OS counts the mapped model file against system RAM even while the server sits idle. It's the model file showing up in the RAM meter, not a leak — but it's worth knowing before you plan headroom on a machine where the GPU is also doing other work.
              </p>

              <!-- Results at a glance -->
              <h2>Results at a glance</h2>
              <p>
                If you only read one table in this post, make it this one — everything else below is detail.
              </p>
              <div class="blog-article-table-wrap">
                <table>
                  <thead>
                    <tr>
                      <th>Model / Quant</th>
                      <th>MTP</th>
                      <th>KV cache</th>
                      <th>Avg throughput</th>
                      <th>Quality (coding task)</th>
                      <th>CPU at eval</th>
                      <th>Context enough?</th>
                      <th>System RAM at eval</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr>
                      <td>unsloth Q4_K_M</td>
                      <td>MTP2 (n=2)</td>
                      <td>32K · q4_0</td>
                      <td><strong>24 TPS</strong></td>
                      <td>Very good reasoning</td>
                      <td>~44%</td>
                      <td>No — had to <code>/compact</code></td>
                      <td>~1.5 GB</td>
                    </tr>
                    <tr>
                      <td>unsloth Q4_K_M</td>
                      <td>off</td>
                      <td>32K · q4_0</td>
                      <td><strong>17 TPS</strong></td>
                      <td>Very good reasoning</td>
                      <td>~25%</td>
                      <td>No — had to <code>/compact</code></td>
                      <td>~1.5 GB</td>
                    </tr>
                    <tr class="row-best">
                      <td>AtomicChat AD-IQ4_XS-IQ3_S</td>
                      <td>MTP2 (n=2)</td>
                      <td>64K · q4_0</td>
                      <td><strong>42 TPS</strong></td>
                      <td>Good reasoning</td>
                      <td>~27%</td>
                      <td>Yes</td>
                      <td>~1 GB</td>
                    </tr>
                    <tr>
                      <td>AtomicChat AD-IQ4_XS-IQ3_S</td>
                      <td>off</td>
                      <td>64K · q4_0</td>
                      <td><strong>27.5 TPS</strong></td>
                      <td>Very good — ~identical to unsloth</td>
                      <td>~24%</td>
                      <td>Yes</td>
                      <td>~1 GB</td>
                    </tr>
                  </tbody>
                </table>
              </div>
              <p>
                All throughput figures are <strong>averages over the run</strong>, not exact single-sample numbers. The highlighted row is the fastest configuration.
              </p>

              <!-- Methodology -->
              <h2>How the tests were configured</h2>
              <p>
                All four runs share the same base: flash attention on (<code>-fa on</code>), automatic memory fitting disabled (<code>--fit off</code>), a single slot (<code>--parallel 1</code>), q4_0 KV cache for both K and V, and generation sampling of <code>--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0</code>. The KV cache size differed between quantizations (32K vs. 64K), and the MTP runs add <code>--spec-type draft-mtp --spec-draft-n-max 2</code> with a q4_0 draft cache. Full commands per configuration are below.
              </p>

              <!-- Model 1: unsloth -->
              <h2>unsloth Qwen3.8-27B-Q4_K_M.gguf</h2>
              <p>
                The most common 4-bit quantization in the ecosystem — a solid reference point for quality.
              </p>

              <h3>With MTP2, flash attention, single slot, no memory fitting</h3>
              <pre><code>llama-server.exe -m D:\source\llms\unsloth\Qwen3.8-27B-Q4_K_M.gguf -ngl 99 --port 1234 -c 32096 --cache-type-k q4_0 --cache-type-v q4_0 -fa on --fit off --parallel 1 --spec-type draft-mtp --spec-draft-n-max 2 --spec-draft-type-k q4_0 --spec-draft-type-v q4_0 --temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0</code></pre>
              <ul>
                <li><strong>Avg throughput:</strong> ~24 tokens/sec</li>
                <li><strong>Quality:</strong> very good reasoning on the coding task (assessed via the pi harness)</li>
                <li><strong>KV cache:</strong> 32K at q4_0</li>
                <li><strong>CPU usage during eval:</strong> up to ~44%</li>
                <li><strong>Context:</strong> not enough — the 32K window ran out on the full-repo task, so I had to run <code>/compact</code> to continue</li>
                <li><strong>System RAM during eval:</strong> ~1.5 GB</li>
              </ul>

              <h3>Flash attention, single slot, no memory fitting (no MTP)</h3>
              <pre><code>llama-server.exe -m D:\source\llms\unsloth\Qwen3.8-27B-Q4_K_M.gguf -ngl 99 --port 1234 -c 32096 --cache-type-k q4_0 --cache-type-v q4_0 -fa on --fit off --parallel 1 --temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0</code></pre>
              <ul>
                <li><strong>Avg throughput:</strong> ~17 tokens/sec</li>
                <li><strong>Quality:</strong> very good reasoning on the coding task</li>
                <li><strong>KV cache:</strong> 32K at q4_0</li>
                <li><strong>CPU usage during eval:</strong> up to ~25%</li>
                <li><strong>Context:</strong> not enough — same 32K ceiling, required <code>/compact</code> mid-task</li>
                <li><strong>System RAM during eval:</strong> ~1.5 GB</li>
              </ul>
              <div class="blog-article-img-wrapper">
                <img src="/blog/qwen38-benchmarks/unsloth-with-without-mtp-comparison.webp" width="1138" height="928" alt="MTP2 vs no MTP comparison — unsloth Q4_K_M on 16 GB" class="blog-article-img" loading="lazy" />
                <span class="blog-article-img-caption">MTP2 vs no MTP — unsloth Q4_K_M (avg 24 vs 17 TPS, 32K q4_0 KV cache)</span>
              </div>

              <!-- Model 2: AtomicChat -->
              <h2>AtomicChat Qwen3.8-27B-AD-IQ4_XS-IQ3_S.gguf</h2>
              <p>
                A mixed-precision dynamic quantization (IQ4_XS with an IQ3_S layer set). The interesting part: it's small enough in practice to give the 64K KV cache real room to breathe.
              </p>

              <h3>With MTP2, flash attention, single slot, no memory fitting</h3>
              <pre><code>llama-server.exe -m D:\source\llms\atomic\Qwen3.8-27B-AD-IQ4_XS-IQ3_S.gguf -ngl 99 --port 1234 -c 64096 --cache-type-k q4_0 --cache-type-v q4_0 -fa on --fit off --parallel 1 --spec-type draft-mtp --spec-draft-n-max 2 --spec-draft-type-k q4_0 --spec-draft-type-v q4_0 --temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0</code></pre>
              <ul>
                <li><strong>Avg throughput:</strong> ~42 tokens/sec — the fastest configuration tested</li>
                <li><strong>Quality:</strong> good reasoning on the coding task — a step below the other three runs</li>
                <li><strong>KV cache:</strong> 64K at q4_0</li>
                <li><strong>CPU usage during eval:</strong> up to ~27%</li>
                <li><strong>Context:</strong> enough — the full-repo task completed without <code>/compact</code></li>
                <li><strong>System RAM during eval:</strong> ~1 GB</li>
              </ul>

              <h3>Flash attention, single slot, no memory fitting (no MTP)</h3>
              <pre><code>llama-server.exe -m D:\source\llms\atomic\Qwen3.8-27B-AD-IQ4_XS-IQ3_S.gguf -ngl 99 --port 1234 -c 64096 --cache-type-k q4_0 --cache-type-v q4_0 -fa on --fit off --parallel 1 --temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0</code></pre>
              <ul>
                <li><strong>Avg throughput:</strong> ~27.5 tokens/sec</li>
                <li><strong>Quality:</strong> very good reasoning — output nearly identical to unsloth Q4_K_M on this task</li>
                <li><strong>KV cache:</strong> 64K at q4_0</li>
                <li><strong>CPU usage during eval:</strong> up to ~24%</li>
                <li><strong>Context:</strong> enough — full-repo task completed without <code>/compact</code></li>
                <li><strong>System RAM during eval:</strong> ~1 GB</li>
              </ul>
              <div class="blog-article-img-wrapper">
                <img src="/blog/qwen38-benchmarks/atomicchat-with-without-mtp-comparison.webp" width="1138" height="928" alt="MTP2 vs no MTP comparison — AtomicChat AD-IQ4_XS-IQ3_S on 16 GB" class="blog-article-img" loading="lazy" />
                <span class="blog-article-img-caption">MTP2 vs no MTP — AtomicChat AD-IQ4_XS-IQ3_S (avg 42 vs 27.5 TPS, 64K q4_0 KV cache)</span>
              </div>

              <!-- Quantization analysis -->
              <h2>The quantization analysis behind the numbers</h2>
              <p>
                The <code>AD-IQ4_XS-IQ3_S</code> file comes from <strong>AtomicChat</strong>, who also published a <strong>quantization analysis with the measurements and instructions</strong> behind it. The takeaway for anyone choosing a 4-bit Qwen 3.8 27B quant: <strong>there is effectively no quality loss between the three</strong> — the margins are small across the board:
              </p>
              <ul>
                <li><strong>unsloth Qwen3.8-27B-IQ4_XS.gguf</strong> — at the top of the group</li>
                <li><strong>lmstudio-community Qwen3.8-27B-Q4_K_M.gguf</strong> — still a bit better than AD-IQ4_XS-IQ3_S, by a small margin, but a bit worse than IQ4_XS</li>
                <li><strong>AtomicChat AD-IQ4_XS-IQ3_S</strong> — no meaningful loss against the other two on these measurements</li>
              </ul>
              <p>
                That lines up with my own coding-task impressions above: the no-MTP runs on both quantizations produced nearly identical reasoning quality.
              </p>
              <div class="blog-article-img-wrapper">
                <img src="/blog/qwen38-benchmarks/atomicchat-quant-analysis.webp" width="2232" height="1475" alt="AtomicChat's quantization analysis comparing 4-bit Qwen 3.8 27B quantizations" class="blog-article-img" loading="lazy" />
                <span class="blog-article-img-caption">AtomicChat's quantization analysis — measurements comparing the 4-bit Qwen 3.8 27B quantizations (source: AtomicChat)</span>
              </div>

              <!-- What stands out -->
              <h2>What stands out</h2>
              <ul>
                <li><strong>MTP2 is a real speedup, not a rounding error.</strong> It lifted throughput from 17 → 24 TPS (+41%) on the unsloth quant and from 27.5 → 42 TPS (+53%) on the AtomicChat quant. On this hardware, the drafting cost is clearly worth it.</li>
                <li><strong>But MTP shifts load to the CPU.</strong> CPU utilization during eval was much higher in the unsloth MTP run (up to ~44%) than in its no-MTP baseline (~25%). The AtomicChat MTP run stayed mild (~27%). Worth knowing if your CPU is also busy.</li>
                <li><strong>The 32K context was the practical ceiling of the unsloth Q4_K_M run on this card — not a property of the model.</strong> Q4_K_M is the heaviest quant tested here, and its footprint leaves little VRAM left for the KV cache on 16 GB, so both unsloth configurations ran out on the full-repo task and required <code>/compact</code> to finish. The 64K AtomicChat configurations completed it cleanly. Don't generalize the 32K ceiling to the whole Qwen 3.8 27B line: with a smaller unsloth quant, the same card could hold a larger KV cache, and the answer may change.</li>
                <li><strong>Quality held up better than expected.</strong> The no-MTP AtomicChat run produced reasoning nearly identical to unsloth Q4_K_M on this workload, at 27.5 TPS with lower RAM usage. The one soft spot: AtomicChat <em>with</em> MTP2 felt a step weaker on reasoning quality than its own no-MTP run.</li>
                <li><strong>System RAM is mostly mmap.</strong> The server's memory-mapped model file alone shows ~13 GB of system DDR5 even when idle, plus ~1 GB (AtomicChat) to ~1.5 GB (unsloth) of working set during eval. Don't panic at the RAM meter — most of that 13 GB is the mapped GGUF, not extra copies of the model.</li>
              </ul>

              <!-- Takeaways -->
              <h2>Takeaways</h2>
              <ul>
                <li><strong>Default to AtomicChat AD-IQ4_XS-IQ3_S with MTP2 on a 16 GB card</strong> if you want maximum speed: 42 TPS, 64K context that actually fits real coding workloads, and the lowest system RAM of the four runs — accepting a slight quality trade-off under MTP.</li>
                <li><strong>Pick unsloth Q4_K_M (no MTP, or MTP2 if you can spare the CPU)</strong> if quality is the priority and you accept a 32K context — that ceiling comes from Q4_K_M's footprint on 16 GB, not the model, so a smaller unsloth quant can fit more context.</li>
                <li><strong>Turn on MTP2 by default</strong> and measure your own task: +40–50% tokens per second is a meaningful difference in a coding workflow.</li>
                <li><strong>Leave headroom.</strong> Budget for the ~13 GB system-RAM figure from the server's mmap before you stack other workloads next to it.</li>
              </ul>

              <h2>What's next</h2>
              <p>
                On the roadmap: <strong>unsloth Qwen3.8-27B-IQ4_XS.gguf (15.7 GB)</strong> — a 4-bit dynamic quant that squeezes even closer to the 16 GB ceiling. I flagged it after reading <a href="https://www.reddit.com/r/LocalLLM/comments/1voygm9/running_qwen3827b_dense_fully_on_a_single_rtx/" target="_blank" rel="noopener noreferrer">this r/LocalLLM thread</a> on running Qwen 3.8 27B dense fully on a single card. The analysis above puts IQ4_XS at the top of that group anyway — so quality-wise it's the one to beat if it fits. If it does fit, the KV cache gets whatever is left over — so the context math from this post is exactly what matters there.
              </p>
              <p>
                If you're setting this up from scratch, start with <a href="/blog/run-qwen-3-8-27b-windows-rocm.html">the Qwen 3.8 27B setup guide</a> and come back here for the configuration choices.
              </p>]]></content:encoded>
    </item>
    <item>
      <title>Run Qwen 3.8 27B on Windows with ROCm — Maximum Performance from Your GPU</title>
      <link>https://ataadevs.net/blog/run-qwen-3-8-27b-windows-rocm.html</link>
      <guid isPermaLink="true">https://ataadevs.net/blog/run-qwen-3-8-27b-windows-rocm.html</guid>
      <pubDate>Fri, 14 Aug 2026 21:00:00 GMT</pubDate>
      <description>A follow-up guide to running Qwen 3.8 27B — the state-of-the-art open model that fits a consumer GPU — on Windows with ROCm, built from source for maximum tokens per second.</description>
      <content:encoded><![CDATA[<!-- Introduction -->
              <p>
                There's something satisfying about running a language model on your own hardware. No API keys, no subscriptions, no data leaving your machine. Just you and the model.
              </p>
              <p>
                Not long ago, running a frontier-class model locally meant compromises: small models, weak answers, or handing your data to a cloud service. That's over. <strong>Qwen 3.8 27B</strong> is the current state of the art among open-weight models you can run on consumer hardware — a dense ~27-billion-parameter model with <strong>vision and reasoning</strong>, a <strong>256K-token context window</strong>, and an <strong>Apache 2.0</strong> license. It doesn't need a data center, just one GPU in your own PC.
              </p>
              <p>
                This is a <strong>follow-up to my earlier post, <a href="/blog/running-local-models-llamacpp-rocm.html">Running Local Models with llama.cpp on Windows &amp; ROCm</a></strong>. That one got you running fast with AMD's pre-built binaries — but those binaries have a hidden cost: they're an <strong>older llama.cpp, compiled once for a whole family of GPUs</strong>, and they leave performance on the table. On my own benchmarks, <strong>building the latest llama.cpp from source, tuned to my exact GPU architecture, delivered noticeably higher tokens per second (TPS)</strong>. This guide takes the from-source path.
              </p>

              <h2>Why build from source? (vs. AMD's pre-built binaries)</h2>
              <p>
                AMD ships ready-made llama.cpp binaries that "just work" — that's the route my previous post took. The catch:
              </p>
              <ul>
                <li>They're an <strong>older llama.cpp build</strong> — every release adds faster kernels and better memory handling, and you miss all of it.</li>
                <li>They're compiled <strong>once for a range of GPUs</strong> (e.g. <code>gfx110X-gfx115X-gfx120X</code>) instead of your exact architecture, so the device code can't be fully tuned to your card.</li>
                <li>Building the latest source with <code>GPU_TARGETS</code> set to your GPU's exact <code>gcnArchName</code> uses <strong>newer kernels compiled specifically for your GPU</strong>.</li>
                <li>My before/after benchmarks: <strong>the from-source build beat the pre-built binaries on tokens per second</strong> — most visible on generation-heavy workloads.</li>
              </ul>
              <p>
                The cost is a few extra minutes and one build. Worth it for the most out of your GPU.
              </p>

              <h2>Why Qwen 3.8 27B?</h2>
              <ul>
                <li><strong>100% local</strong> — your conversations never leave your machine</li>
                <li><strong>State of the art</strong> — the dense open-weight model to beat at ~30B parameters</li>
                <li><strong>Free &amp; open</strong> — Apache 2.0 license, official GGUF releases from day one</li>
                <li><strong>Huge context</strong> — a 256K-token window for long documents and deep conversations</li>
                <li><strong>One consumer GPU</strong> — roughly 16–17 GB of VRAM at 4-bit quantization</li>
                <li><strong>Drop-in successor</strong> — same size and architecture as Qwen 3.6 27B, so existing GGUF tooling and configuration just work</li>
              </ul>

              <h2>What you'll have when you're done</h2>
              <ul>
                <li><strong>The latest llama.cpp, built from source for your exact GPU</strong> — higher tokens per second than AMD's pre-built binaries, and your GPU doing the math instead of your CPU</li>
                <li>A <strong>local server speaking the OpenAI API</strong> — point any tool at <code>http://localhost:8080</code></li>
                <li>The <strong>tools, source code, and model</strong> downloaded, ready to rebuild or swap anytime</li>
              </ul>

              <h2>The journey at a glance</h2>
              <ul>
                <li><strong>Step 1 — Install the tools</strong> (driver, ROCm, Visual Studio, Git, CMake, Ninja). <em>You.</em></li>
                <li><strong>Step 2 — Download the llama.cpp source code.</strong> <em>You.</em></li>
                <li><strong>Step 3 — Download the Qwen 3.8 27B model.</strong> <em>You.</em></li>
                <li><strong>Step 4 — Build, verify, and fix any issues.</strong> <em>Your AI assistant</em> — this part has a few sharp edges (GPU architecture, multi-GPU quirks), so it deserves its own detailed checklist: <a href="/blog/BUILD_HIP_WINDOWS.md">BUILD_HIP_WINDOWS.md</a>.</li>
                <li><strong>Step 5 — Start the server and talk to the model.</strong> <em>Both of you.</em></li>
              </ul>
              <p>
                This guide covers steps 1–3 (the downloads). Step 4 is a technical job with a few sharp edges, so it has its own detailed document that your AI assistant will work through — more on that in Part 4.
              </p>

              <!-- Part 1 -->
              <h2>Part 1: Install the tools</h2>
              <p>
                None of these are optional — each one is needed for the build. Do them in order.
              </p>

              <h3>1.1 AMD graphics driver</h3>
              <p>
                Download from <a href="https://www.amd.com/en/support" target="_blank" rel="noopener noreferrer">amd.com/support</a> (pick your GPU). Install, then <strong>restart your PC</strong>.
              </p>

              <h3>1.2 ROCm (AMD's GPU compute kit)</h3>
              <p>
                Go to <a href="https://www.amd.com/en/products/software/rocm.html" target="_blank" rel="noopener noreferrer">amd.com/products/software/rocm</a> and download the <strong>Windows</strong> installer (it's big — several GB). Run the installer. You only need <strong>ROCm Runtime</strong>, <strong>HIP</strong>, and <strong>rocBLAS</strong> — you can skip PyTorch, TensorFlow, profiling tools, MIOpen, and everything else. It lands in <code>C:\Program Files\AMD\ROCm\&lt;version&gt;</code> — remember the version number.
              </p>
              <p>
                Note: ROCm installs a driver component. If your antivirus blocks it, add an exception for <code>C:\Program Files\AMD\ROCm</code> and restart.
              </p>

              <h3>1.3 Visual Studio (Community is free)</h3>
              <p>
                Download from <a href="https://visualstudio.microsoft.com/downloads/" target="_blank" rel="noopener noreferrer">visualstudio.microsoft.com</a>. In the installer's workload list, tick <strong>"Desktop development with C++"</strong>. You don't need anything else.
              </p>

              <h3>1.4 Git</h3>
              <p>
                Download from <a href="https://git-scm.com/download/win" target="_blank" rel="noopener noreferrer">git-scm.com</a> and install with the default options.
              </p>

              <h3>1.5 CMake</h3>
              <p>
                Download the <strong>Windows x64 Installer</strong> from <a href="https://cmake.org/download/" target="_blank" rel="noopener noreferrer">cmake.org</a>. During install, tick <strong>"Add CMake to the system PATH"</strong>.
              </p>

              <h3>1.6 Ninja</h3>
              <p>
                Download <code>ninja-win.zip</code> from <a href="https://github.com/ninja-build/ninja/releases" target="_blank" rel="noopener noreferrer">github.com/ninja-build/ninja/releases</a> (get the newest release), or run <code>winget install Ninja-build.Ninja</code>. If you downloaded the zip: unzip it, put <code>ninja.exe</code> in a folder that's on your PATH (e.g. <code>C:\Ninja</code>), and add that folder to your PATH in <em>System Properties → Environment Variables</em>.
              </p>

              <!-- Part 2 -->
              <h2>Part 2: Get the source code</h2>
              <p>
                <strong>llama.cpp</strong> is the engine that runs GGUF models like ours. Open PowerShell (or Git Bash) and run:
              </p>
              <pre><code>git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp</code></pre>
              <p>
                The build itself happens later, with the AI's help — for now, downloading is enough.
              </p>

              <!-- Part 3 -->
              <h2>Part 3: Get the model: Qwen 3.8 27B</h2>
              <ol>
                <li>
                  <strong>Download the 4-bit GGUF</strong> from either of these (both are official community quants):
                  <ul>
                    <li><a href="https://huggingface.co/lmstudio-community/Qwen3.8-27B-GGUF" target="_blank" rel="noopener noreferrer">lmstudio-community/Qwen3.8-27B-GGUF</a> — grab the file <code>Qwen3.8-27B-Q4_K_M.gguf</code> (LM Studio community, built with llama.cpp)</li>
                    <li>or <a href="https://huggingface.co/unsloth/Qwen3.8-27B-GGUF" target="_blank" rel="noopener noreferrer">unsloth/Qwen3.8-27B-GGUF</a> — Unsloth's dynamic 4-bit GGUFs</li>
                  </ul>
                </li>
                <li>
                  <strong>Check your VRAM first</strong> (Task Manager → Performance → GPU). A 4-bit 27B needs <strong>16–17 GB</strong> — a 16 GB+ GPU is required. Less VRAM? Download <code>Q3_K_M</code> instead, or pick a smaller model; the steps stay the same.
                </li>
                <li>
                  Download the <code>.gguf</code> file to a folder you'll remember, e.g. <code>D:\models\</code>. Keep the full path handy — you'll need it later.
                </li>
              </ol>

              <!-- Part 4 -->
              <h2>Part 4: Hand over to the AI</h2>
              <p>
                Your PC is now ready. Point your AI assistant at the technical checklist — <a href="/blog/BUILD_HIP_WINDOWS.md">BUILD_HIP_WINDOWS.md</a> — it will:
              </p>
              <ul>
                <li>Find your ROCm install and check your GPU's exact architecture</li>
                <li>Configure and build llama.cpp with the ROCm backend</li>
                <li>Verify the GPU is actually being used</li>
                <li>Fix anything that goes wrong</li>
              </ul>
              <p>
                <strong>One thing to tell the AI before it starts:</strong> does your PC also have <strong>integrated graphics</strong>? (Windows shows a second GPU like "AMD Radeon(TM) Graphics" next to your real one.) If yes, say so — it changes how the setup is done and avoids a very common startup crash.
              </p>

              <!-- Wrap up -->
              <h2>Wrapping Up</h2>
              <p>
                Running a frontier-class model locally isn't just practical — with the from-source build, it's the fastest option available on your hardware. No cloud, no subscriptions, no data leaving your machine; just the latest kernels, tuned to your exact GPU.
              </p>
              <p>
                If you followed the previous post with AMD's pre-built binaries, you already know how far this goes. Now imagine the same setup with noticeably more tokens per second. That's what building from source buys you.
              </p>
              <p>
                The model we used is just the start. The GGUF ecosystem has hundreds of models on <a href="https://huggingface.co/models?library=gguf" target="_blank" rel="noopener noreferrer">Hugging Face</a> — pick one that fits your VRAM and start experimenting. Welcome to local AI.
              </p>]]></content:encoded>
    </item>
    <item>
      <title>Running Local Models with llama.cpp on Windows &amp; ROCm</title>
      <link>https://ataadevs.net/blog/running-local-models-llamacpp-rocm.html</link>
      <guid isPermaLink="true">https://ataadevs.net/blog/running-local-models-llamacpp-rocm.html</guid>
      <pubDate>Tue, 28 Jul 2026 21:00:00 GMT</pubDate>
      <description>A step-by-step guide to running local LLMs on Windows with AMD GPUs using llama.cpp and ROCm — no cloud, no subscriptions.</description>
      <content:encoded><![CDATA[<!-- Introduction -->
              <p>
                There's something satisfying about running a language model on your own hardware. No API keys, no subscriptions, no data leaving your machine. Just you and the model.
              </p>
              <p>
                If you have an AMD GPU and a Windows machine, you're in luck. With <strong>llama.cpp</strong> and <strong>ROCm</strong>, you can run models locally with performance that rivals — and sometimes beats — tools like LM Studio. The catch? Building llama.cpp from source on Windows with ROCm support is notoriously painful. But luckily, AMD provides pre-built binaries that skip all that hassle.
              </p>
              <p>
                This guide walks you through two things:
              </p>
              <ul>
                <li><strong>Part 1:</strong> Installing the C++ build dependencies you'll need via Visual Studio</li>
                <li><strong>Part 2:</strong> Downloading and running llama.cpp with a real model on your AMD GPU</li>
              </ul>

              <!-- Part 1 -->
              <h2>Part 1: Setting Up C++ Dependencies with Visual Studio</h2>

              <p>
                Before we touch llama.cpp, we need to make sure your system has the C++ build tools installed. Even though we're using pre-built binaries (not compiling from source), some dependencies and runtime libraries still expect these to be present.
              </p>

              <h3>Step 1: Open Visual Studio Installer</h3>
              <p>
                If you don't have it yet, download <strong>Visual Studio Community</strong> from <a href="https://visualstudio.microsoft.com/" target="_blank" rel="noopener noreferrer">visualstudio.microsoft.com</a>. If it's already installed, open the Visual Studio Installer from your Start Menu.
              </p>
              <p>
                You'll land on a screen like this — click the <strong>Modify</strong> button (or <strong>Install</strong> if it's a fresh install):
              </p>
              <div class="blog-article-img-wrapper">
                <img src="/blog/visual-studio-installer-home.webp" width="1276" height="716" alt="Visual Studio Installer home screen showing the Modify button" class="blog-article-img" loading="lazy" />
                <span class="blog-article-img-caption">Visual Studio Installer — click Modify to add workloads</span>
              </div>

              <h3>Step 2: Select the Right Workloads</h3>
              <p>
                In the <strong>Workloads</strong> tab, check the following:
              </p>
              <ul>
                <li><strong>.NET desktop development</strong> — provides core .NET runtime tools and C# support</li>
                <li><strong>Desktop development with C++</strong> — this is the important one. It installs the MSVC compiler, Windows SDK, and C++ standard libraries that llama.cpp binaries depend on at runtime</li>
              </ul>
              <p>
                On the right panel, make sure the optional components are checked — especially anything related to C++ build tools and the latest Windows SDK.
              </p>
              <div class="blog-article-img-wrapper">
                <img src="/blog/visual-studio-installer-workloads.webp" width="1278" height="718" alt="Visual Studio Installer workloads screen with .NET desktop development and Desktop development with C++ selected" class="blog-article-img" loading="lazy" />
                <span class="blog-article-img-caption">Select .NET desktop development and Desktop development with C++</span>
              </div>

              <h3>Step 3: Install / Modify</h3>
              <p>
                Click <strong>Install</strong> (or <strong>Modify</strong>) in the bottom right corner. The installer will download and set up everything. It takes a few minutes depending on your connection.
              </p>
              <p>
                Once it's done, you're ready for the fun part.
              </p>

              <!-- Part 2 -->
              <h2>Part 2: Running Local Models with llama.cpp</h2>

              <p>
                <strong>llama.cpp</strong> is a lightweight C++ implementation of Meta's LLaMA architecture. It runs models in the GGUF format directly on your hardware. Combined with ROCm (AMD's GPU compute platform), it can offload model layers to your AMD GPU for serious speed.
              </p>
              <p>
                Why not use something like LM Studio? LM Studio is great for getting started, but it abstracts away control. With llama.cpp, you get:
              </p>
              <ul>
                <li>Full control over context length, GPU layers, and sampling parameters</li>
                <li>An OpenAI-compatible API server you can plug into any tool</li>
                <li>Benchmarking tools to actually measure your hardware's performance</li>
                <li>No Electron overhead — just a single executable</li>
              </ul>
              <p>
                The downside? Building from source on Windows with ROCm is a nightmare. But AMD publishes <strong>pre-built binaries</strong> that just work.
              </p>

              <h3>Step 1: Download the Pre-built Binaries</h3>
              <p>
                AMD hosts validated builds at <a href="https://repo.radeon.com/rocm/llama.cpp/windows" target="_blank" rel="noopener noreferrer">repo.radeon.com/rocm/llama.cpp/windows</a>. Grab the latest package:
              </p>
              <pre><code>curl.exe -o llama-bin-windows.zip "https://repo.radeon.com/rocm/llama.cpp/windows/rocm-rel-7.2.1/llama-b8407-windows-rocm-7.2.1-gfx110X-gfx115X-gfx120X-x64.zip"</code></pre>

              <h3>Step 2: Extract the Archive</h3>
              <p>
                Unzip it into a clean directory:
              </p>
              <pre><code>Expand-Archive -Path "llama-bin-windows.zip" -DestinationPath ".\llama_cpp_binaries"</code></pre>
              <p>
                Then navigate into the inner folder:
              </p>
              <pre><code>cd ./llama_cpp_binaries/&lt;specific_folder_name&gt;</code></pre>

              <h3>Step 3: Download a Model</h3>
              <p>
                The binaries are the engine — you still need a model file (in <strong>GGUF format</strong>) to actually run something. For testing, we'll grab GPT-OSS-20B:
              </p>
              <pre><code>curl.exe -L -o test_model.gguf "https://huggingface.co/ggml-org/gpt-oss-20b-GGUF/resolve/main/gpt-oss-20b-mxfp4.gguf"</code></pre>
              <p>
                This is a ~20B parameter model. Depending on your GPU VRAM, you might want to pick a smaller model. The process is the same regardless.
              </p>

              <h3>Step 4: Start the Server</h3>
              <p>
                <strong>llama-server</strong> is a lightweight, OpenAI-compatible web server included with llama.cpp. It hosts your model locally and gives you a chat interface in your browser.
              </p>
              <pre><code># Start the server
# -ngl 99: Offload all layers to your AMD GPU (Crucial for performance)
# -c: Context Length
# -fa: Enable Flash Attention to reduce memory usage and increase speed
.\llama-server.exe -m test_model.gguf -c 2048 -ngl 99 -fa on --port 8080</code></pre>
              <p>
                Open your browser and go to <code>http://localhost:8080</code>. You'll see a clean chat interface where you can talk to the model.
              </p>
              <p>
                The <code>-ngl 99</code> flag is key — it tells llama.cpp to offload all model layers to your AMD GPU. Without it, you're running on CPU, which is painfully slow for anything beyond tiny models.
              </p>

              <h3>Step 5: (Optional) Run a Benchmark</h3>
              <p>
                Want to know how fast your GPU is actually running? Use the built-in benchmark tool:
              </p>
              <pre><code># Run the benchmark with the downloaded model.
# -m: specifies the model file
.\llama-bench.exe -m .\test_model.gguf -fa 1</code></pre>
              <p>
                This will output two key metrics:
              </p>
              <ul>
                <li><strong>PP (Prompt Processing)</strong> — how fast the model processes your input</li>
                <li><strong>TG (Token Generation)</strong> — how fast it generates output tokens</li>
              </ul>
              <p>
                These numbers are useful for comparing different models or tuning your <code>-ngl</code> and <code>-c</code> parameters.
              </p>

              <!-- Wrap up -->
              <h2>Wrapping Up</h2>
              <p>
                Running local models isn't just a novelty — it's becoming practical. With AMD GPUs and pre-built llama.cpp binaries, you can have a fully local, OpenAI-compatible API running on your machine in under 10 minutes.
              </p>
              <p>
                The model we used (GPT-OSS-20B) is just a starting point. The GGUF ecosystem has hundreds of models available on <a href="https://huggingface.co/models?library=gguf" target="_blank" rel="noopener noreferrer">Hugging Face</a>, from tiny 1B models to 70B+ beasts. Pick one that fits your VRAM and start experimenting.
              </p>
              <p>
                I'll be writing more about practical AI engineering — building agents, running inference, and shipping AI-powered products. Follow along if that's your thing.
              </p>]]></content:encoded>
    </item>
    <item>
      <title>beautiful-sign-language-tr — Recognizing Turkish Sign Language with Deep Learning</title>
      <link>https://ataadevs.net/blog/beautiful-sign-language-tr.html</link>
      <guid isPermaLink="true">https://ataadevs.net/blog/beautiful-sign-language-tr.html</guid>
      <pubDate>Thu, 09 Jun 2022 21:00:00 GMT</pubDate>
      <description>An open-source deep learning system for recognizing Turkish sign language from video input, supporting both word-level and sentence-level recognition.</description>
      <content:encoded><![CDATA[<p>
                I started <strong>beautiful-sign-language-tr</strong> as a proof of concept — the idea that a camera and some deep learning models could recognize Turkish sign language gestures without any special hardware. Just a webcam, a video feed, and a neural network doing its thing.
              </p>
              <p>
                The goal was never to build a finished product. It was to build a <strong>starting point</strong> — something others could contribute to, improve, and eventually turn into a real system that helps hearing-impaired people communicate more easily.
              </p>

              <div class="blog-article-img-wrapper">
                <img src="/blog/gifs/sign-language-recognition-demo.gif" width="480" height="270" alt="Sign language recognition demo" class="blog-article-img" loading="lazy" />
              </div>

              <h2>How It Works</h2>
              <p>
                The system supports two modes of operation:
              </p>

              <h3>Word-Level Recognition</h3>
              <p>
                Each sign language gesture is treated as an independent input. You perform a word, press 'q' to stop recording, and the model predicts what you signed. It's <strong>accurate, simple, and fast</strong> — perfect for real-time use.
              </p>
              <ul>
                <li>Input space is discrete — each video is one word</li>
                <li>Returns top-<em>n</em> predictions sorted by confidence</li>
                <li>Works with any camera (webcam, phone, etc.)</li>
              </ul>

              <h3>Sentence-Level Recognition</h3>
              <p>
                The system can also accept continuous input — sentences rather than individual words. It's slower and less accurate than word-level, but it handles real-world input where you don't pause between words.
              </p>
              <ul>
                <li>Input space is continuous</li>
                <li>Accepts any video format (mp4, flv, webm, etc.)</li>
                <li>More flexible, but trades off speed and accuracy</li>
              </ul>

              <h2>Results</h2>

              <p><strong>Word-level system:</strong></p>
              <div class="blog-article-img-wrapper">
                <img src="/blog/gifs/sign-language-word-level.gif" width="480" height="270" alt="Word-level recognition results" class="blog-article-img" loading="lazy" />
              </div>

              <p><strong>Sentence-level system:</strong></p>
              <div class="blog-article-img-wrapper">
                <img src="/blog/gifs/sign-language-sentence-level.gif" width="480" height="270" alt="Sentence-level recognition results" class="blog-article-img" loading="lazy" />
              </div>

              <h2>Features</h2>
              <ul>
                <li><strong>REST API</strong> — serve the system as an HTTP endpoint, making it easy to integrate into any application without mixing Python dependencies</li>
                <li><strong>WampServer / Xampp</strong> — local web interface for testing, with a simple UI demonstrating use cases</li>
                <li><strong>Multiprocessing</strong> — the full pipeline is multi-processed for performance (though some OS-level quirks on Windows can cause bottlenecks)</li>
                <li><strong>CPU &amp; GPU</strong> — runs on both; GPU support requires CUDA and cuDNN</li>
                <li><strong>OS</strong> — tested on Ubuntu 18 and Windows 10</li>
              </ul>

              <h2>Quick Start</h2>
              <p>
                Clone the repo and install requirements:
              </p>
              <pre><code>git clone https://github.com/AtaaEddin/beautiful-sign-language-tr
cd beautiful-sign-language-tr
pip install -r requirements.txt</code></pre>

              <p>
                Run a quick webcam test:
              </p>
              <pre><code>python main.py -run webcam -pred_type word -download True</code></pre>
              <p>
                While it's running, perform one of the <a href="https://www.youtube.com/playlist?list=PLxVilKcX9J7Siru_n8Dy1NajiH0CR8EwP" target="_blank" rel="noopener noreferrer">10 supported Turkish sign language words</a>, then press 'q' to end recording and get a prediction.
              </p>

              <h2>How to Contribute</h2>
              <p>
                This project was designed to grow with the community. If you want to help:
              </p>
              <ul>
                <li>Find or create a sign language video dataset (even recording with your phone works)</li>
                <li>Label the videos and train using the existing models</li>
                <li>Open an issue describing your dataset and training results</li>
                <li>We'll merge datasets and do overall training together</li>
              </ul>
              <p>
                All submitted datasets will be made publicly available for anyone who wants to train using this project's models or their own.
              </p>

              <h2>What's Next</h2>
              <p>
                The system currently recognizes 10 Turkish sign language words, but the dream is to scale that up significantly — hundreds of words, full sentences, and real-time performance that makes it usable in daily life.
              </p>
              <p>
                The code is open source on <a href="https://github.com/AtaaEddin/beautiful-sign-language-tr" target="_blank" rel="noopener noreferrer">GitHub</a>. If this interests you, contribute, open issues, or just star the repo to show support.
              </p>]]></content:encoded>
    </item>
    <item>
      <title>Interactive ChatBot in Turkish</title>
      <link>https://ataadevs.net/blog/interactive-chatbot-turkish.html</link>
      <guid isPermaLink="true">https://ataadevs.net/blog/interactive-chatbot-turkish.html</guid>
      <pubDate>Tue, 19 Mar 2019 21:00:00 GMT</pubDate>
      <description>A seq2seq chatbot trained on Turkish Twitter data with a human-like voice interface and wake word detection.</description>
      <content:encoded><![CDATA[<div class="blog-article-img-wrapper">
                <img src="/blog/gifs/chatbot-interaction-demo.gif" width="480" height="270" alt="ChatBot interaction demo" class="blog-article-img" loading="lazy" />
              </div>

              <p>
                This was one of my earlier projects — a chatbot that could hold a conversation in Turkish, complete with a wake word to activate it and a physical-looking interface to interact with. The idea was simple: train a sequence-to-sequence model on Turkish Twitter conversations and make it feel like talking to someone.
              </p>
              <p>
                The query <em>"sen güzel bir kızsın"</em> (you're a beautiful girl) would get a response like <em>"sen daha güzelsin!!"</em> (you're even more beautiful!!). Not perfect, but fun.
              </p>

              <h2>How It Works</h2>
              <p>
                The system has two main parts:
              </p>

              <h3>1. Trigger Word Detection</h3>
              <p>
                Before you can talk to the bot, you need to wake it up — just like saying "Alexa" to an Amazon Echo. Our trigger phrase was <strong>"uyan ay"</strong> (wake up, moon). When the bot hears it, it activates and starts listening.
              </p>

              <div class="blog-article-img-wrapper">
                <img src="/blog/gifs/chatbot-wake-word-demo.gif" width="480" height="270" alt="Trigger word detection demo" class="blog-article-img" loading="lazy" />
              </div>

              <h3>2. ChatBot (Seq2Seq Model)</h3>
              <p>
                The chatbot is a task-specific system focused on general conversation. For any input text — a question, a joke, a statement — it generates a response derived from patterns it learned from Turkish Twitter data.
              </p>
              <p>
                The flow is:
              </p>
              <ul>
                <li><strong>Voice → Text:</strong> Your speech is converted to text using Google's voice recognition API</li>
                <li><strong>Text → Text:</strong> The seq2seq model generates a response</li>
                <li><strong>Text → Voice:</strong> The response is spoken back through the human interface</li>
              </ul>

              <p>
                <strong>query:</strong> <em>seni çok seviyorum.</em> (I love you so much.)
              </p>
              <p>
                <strong>ChatBot:</strong> <em>ben de seni çok seviyorum yanımızda olduğun için sonsuz teşekkürler.</em> (I love you too, thank you so much for being with us.)
              </p>

              <div class="blog-article-img-wrapper">
                <img src="/blog/gifs/chatbot-response-demo.gif" width="480" height="270" alt="ChatBot responding to query" class="blog-article-img" loading="lazy" />
              </div>

              <h2>Tech Stack</h2>
              <ul>
                <li><strong>Python 3</strong></li>
                <li><strong>TensorFlow</strong> ≤ 1.11.0 — for the seq2seq model</li>
                <li><strong>TensorLayer</strong> ≥ 1.6.3 — high-level deep learning library</li>
                <li>Google Voice Recognition API — for speech-to-text</li>
                <li>Internet connection required for voice APIs</li>
              </ul>

              <h2>Installation</h2>
              <p><strong>Ubuntu:</strong></p>
              <pre><code>sudo apt install libasound-dev portaudio19-dev libportaudio2 libportaudiocpp0 ffmpeg libav-tools
sudo apt-get install python3-tk
pip3 install -r requirements.txt</code></pre>

              <p><strong>Windows:</strong></p>
              <pre><code>pip install -r requirements.txt</code></pre>

              <h2>Running It</h2>
              <pre><code># Ubuntu (Python 3)
python3 my_robot.py

# Ubuntu (Python 2)
python my_robot.py

# Windows
python my_robot.py</code></pre>

              <h2>Looking Back</h2>
              <p>
                This project taught me a lot about NLP, sequence models, and the challenges of working with Turkish — a language with complex morphology that doesn't play nicely with standard tokenization. The seq2seq approach was state-of-the-art at the time, before transformers took over.
              </p>
              <p>
                If I were to rebuild this today, I'd use a fine-tuned transformer model and skip the voice recognition API entirely — running Whisper locally would make the whole thing work offline. But that's the beauty of old projects: they show you how far the field has come.
              </p>]]></content:encoded>
    </item>
  </channel>
</rss>
