<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PEPPERCORN</title>
    <description>The latest articles on DEV Community by PEPPERCORN (@peppercorn_llm).</description>
    <link>https://dev.to/peppercorn_llm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3910738%2F8084bbca-3641-4d19-85b2-f53a184e1f84.jpg</url>
      <title>DEV Community: PEPPERCORN</title>
      <link>https://dev.to/peppercorn_llm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/peppercorn_llm"/>
    <language>en</language>
    <item>
      <title>[Day 18] I set up a company of AI agents with Claude Code — and a local LLM (qwen) joined as the caretaker</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Sat, 25 Jul 2026 00:16:28 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-18-i-set-up-a-company-of-ai-agents-with-claude-code-and-a-local-llm-qwen-joined-as-the-2jo3</link>
      <guid>https://dev.to/peppercorn_llm/day-18-i-set-up-a-company-of-ai-agents-with-claude-code-and-a-local-llm-qwen-joined-as-the-2jo3</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 18!&lt;/p&gt;

&lt;p&gt;In Day 17 I audited 33,469 of my own AI conversations. Building on that, today I set up a company of cats to run my task management 🐱&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: Claude Code / DGX Spark / Slack &amp;amp; Notion.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Today's plan
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What I want&lt;/strong&gt;: hand the annoying parts of task management to a company of cats&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approach&lt;/strong&gt;: build in order — the org, the task flow, the ledger, AI collaboration rules, then deploy to both machines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Done means&lt;/strong&gt;: every morning, Necco and I pick "today's three tasks"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Result&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;A company of six cats. Inbox = Slack, source of truth = Notion, memory = the ledger&lt;/li&gt;
&lt;li&gt;I inventoried my projects: &lt;strong&gt;80&lt;/strong&gt; of them. All in the ledger now&lt;/li&gt;
&lt;li&gt;One page of collaboration rules for Claude Code / Codex / qwen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ① Built the org
&lt;/h2&gt;

&lt;p&gt;Role-based staff (subagents), all named "___-neko" (neko = cat).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Necco&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Chief secretary: morning meeting, task triage, routing, ledger upkeep&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shirabe-neko&lt;/td&gt;
&lt;td&gt;Research&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tsukuri-neko&lt;/td&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mekiki-neko&lt;/td&gt;
&lt;td&gt;Review (read-only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Soroban-neko&lt;/td&gt;
&lt;td&gt;Number crunching&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rusuban-neko&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Caretaker: &lt;strong&gt;a local LLM (qwen) living on the DGX&lt;/strong&gt;. Summarizes, sorts, and tags incoming files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Before building, I looked at prior art. An individual delegating their own management to AI seems established as the &lt;strong&gt;AI Chief of Staff&lt;/strong&gt; pattern.&lt;/p&gt;

&lt;p&gt;The staff internals come tomorrow in Day 19.&lt;/p&gt;




&lt;h2&gt;
  
  
  ② Built the task flow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A task pops up → one line into Slack from my phone (3 seconds)
             → [morning meeting] Necco sweeps the inbox
             → cleans it up, adds a due date, registers it in Notion
             → proposes "today's three"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of something, drop one line in Slack. By morning it's in Notion. An evening "done: ___" one-liner feeds the next morning's ledger update and task close-out.&lt;/p&gt;




&lt;h2&gt;
  
  
  ③ Built the ledger
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's the ledger (LEDGER.md)?&lt;/strong&gt; One file listing every project, so Necco can answer "where was that project again?" instantly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the initial data, I inventoried both of my machines. The count: &lt;strong&gt;80 projects&lt;/strong&gt;. I had no idea it was that many...&lt;/p&gt;




&lt;h2&gt;
  
  
  ④ Set the AI collaboration rules
&lt;/h2&gt;

&lt;p&gt;Instead of deciding "which AI gets this job" every time, it's now one page:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AI&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Lead (design, planning, review, conversation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codex CLI&lt;/td&gt;
&lt;td&gt;Routine subcontractor (implementation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen (local LLM)&lt;/td&gt;
&lt;td&gt;Batch pre-processing (summarize, sort, tag — stays on the DGX)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Rusuban-neko is the DGX side of this rule. Zero API cost, and the data never leaves the house.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⑤ Deployed to both machines
&lt;/h2&gt;

&lt;p&gt;The company is a git repository. I gave it a private GitHub remote and cloned it onto the DGX. An install script places the staff and skills into &lt;code&gt;~/.claude/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now either machine can summon the same company.&lt;/p&gt;




&lt;h2&gt;
  
  
  The first morning meeting
&lt;/h2&gt;

&lt;p&gt;I opened Claude Code in the office and ran the first morning meeting.&lt;/p&gt;

&lt;p&gt;The one-liner I had tossed into Slack the night before was cleaned up and registered in Notion by Necco. This is genuinely comfortable.&lt;/p&gt;




&lt;h2&gt;
  
  
  The full picture
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Chief secretary&lt;/td&gt;
&lt;td&gt;Necco (Claude Code)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Staff&lt;/td&gt;
&lt;td&gt;Shirabe / Tsukuri / Mekiki / Soroban (subagents)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caretaker&lt;/td&gt;
&lt;td&gt;Rusuban-neko (local qwen on the DGX)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inbox&lt;/td&gt;
&lt;td&gt;Slack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source of truth&lt;/td&gt;
&lt;td&gt;Notion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;the ledger file (80 projects)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Slack&lt;/td&gt;
&lt;td&gt;The &lt;strong&gt;inbox&lt;/strong&gt; — ephemeral, free-form, 3 seconds to post&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notion&lt;/td&gt;
&lt;td&gt;The &lt;strong&gt;source of truth&lt;/strong&gt; — same as before&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ledger&lt;/td&gt;
&lt;td&gt;The company &lt;strong&gt;memory&lt;/strong&gt; — what exists, where, in what state&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;secretary/                   ← the office (cloned on both machines)
  CLAUDE.md                  ← Necco's persona, house rules, meeting runbook
  LEDGER.md                  ← the ledger (80 projects)
  input/                     ← file inbox (pre-processed by Rusuban-neko)
  agents/                    ← staff definitions (source of truth)
  skills/                    ← skills (source of truth)
  install.sh / install.ps1   ← places staff &amp;amp; skills into ~/.claude/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notion stays; only the entrance changed. Necco does the formatting and registering.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separate the inbox from the source of truth&lt;/strong&gt;: Notion felt tedious because it was doing both jobs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep the company's memory in git&lt;/strong&gt;: AI auto-memory splits across two machines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default patterns are fine&lt;/strong&gt;: borrow the shape from prior art, fit the details to your own setup&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The morning meeting runbook (8 steps)&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;git pull&lt;/code&gt; (bring in the other machine's updates)&lt;/li&gt;
&lt;li&gt;Rusuban-neko pre-processes anything new in &lt;code&gt;input/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Close out yesterday's three (update Notion statuses)&lt;/li&gt;
&lt;li&gt;Sweep the Slack inbox → turn into TODOs → register in Notion&lt;/li&gt;
&lt;li&gt;Notion + calendar + inbox + ledger → propose "today's three"&lt;/li&gt;
&lt;li&gt;Reflect the evening one-liners into the ledger&lt;/li&gt;
&lt;li&gt;Post the final digest to Slack&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Git sync (1 and 8) and close-out (3) are baked into the runbook. The human only "posts" and "answers".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pitfalls I mapped out beforehand&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pitfall&lt;/th&gt;
&lt;th&gt;Countermeasure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The ledger goes stale&lt;/td&gt;
&lt;td&gt;The evening one-liner habit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI memory splits across two machines&lt;/td&gt;
&lt;td&gt;Permanent knowledge goes into git-tracked files; auto-memory is treated as cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forgetting to sync the two machines&lt;/td&gt;
&lt;td&gt;pull / push are steps 1 and 8 of the runbook&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Work calendar isn't visible&lt;/td&gt;
&lt;td&gt;Fill in verbally at the morning meeting, for now&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No closed loop on task completion&lt;/td&gt;
&lt;td&gt;The meeting starts with closing out yesterday's three&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Two-machine sync&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Staff definitions (&lt;code&gt;agents/&lt;/code&gt;) and skills (&lt;code&gt;skills/&lt;/code&gt;) live in the repository as the source of truth&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;install.sh&lt;/code&gt; (Linux) / &lt;code&gt;install.ps1&lt;/code&gt; (Windows) place them into &lt;code&gt;~/.claude/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Adding a staff member = commit → pull on the other machine → run install&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prior-art notes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/mimurchison/claude-chief-of-staff" rel="noopener noreferrer"&gt;mimurchison/claude-chief-of-staff&lt;/a&gt;: CLAUDE.md at the core; goals filter every priority; humans keep the final say&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jonesrussell.github.io/blog/claudia-ai-chief-of-staff/" rel="noopener noreferrer"&gt;Claudia&lt;/a&gt;: remembers promises and relationships; a messaging gateway from your phone&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/loganhc-09/claude-chief-of-staff" rel="noopener noreferrer"&gt;loganhc-09/claude-chief-of-staff&lt;/a&gt;: resident operation via scheduled scripts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common rule: always-on rules → CLAUDE.md / occasional methods → skills / context-heavy work → subagents. This build follows it too.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tomorrow: Day 19
&lt;/h2&gt;

&lt;p&gt;Staff day — the four subagent definition files, plus getting Rusuban-neko (the local LLM) running as a resident service.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>agents</category>
    </item>
    <item>
      <title>[Day 17] I analyzed 33,469 of my own AI conversations to audit how I actually use AI</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Thu, 23 Jul 2026 04:34:59 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-17-i-analyzed-33469-of-my-own-ai-conversations-to-audit-how-i-actually-use-ai-27ap</link>
      <guid>https://dev.to/peppercorn_llm/day-17-i-analyzed-33469-of-my-own-ai-conversations-to-audit-how-i-actually-use-ai-27ap</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 17!&lt;/p&gt;

&lt;p&gt;Today I &lt;strong&gt;collected everything I've ever said to an AI and had a local model read it back to me&lt;/strong&gt;. Seventeen months of history — then a self-audit of how I actually use these tools, and where the easy wins are.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What I collected&lt;/th&gt;
&lt;th&gt;Messages&lt;/th&gt;
&lt;th&gt;Mine only&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ChatGPT (browser)&lt;/td&gt;
&lt;td&gt;10,002&lt;/td&gt;
&lt;td&gt;4,964&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude (browser)&lt;/td&gt;
&lt;td&gt;10,937&lt;/td&gt;
&lt;td&gt;5,482&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terminal (Claude Code, Codex CLI)&lt;/td&gt;
&lt;td&gt;12,530&lt;/td&gt;
&lt;td&gt;3,518&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;33,469&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;13,964&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: DGX Spark (my home AI machine) / qwen2.5 (the local model doing the analysis).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu0pkeaj8bp7gumcsu9w4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu0pkeaj8bp7gumcsu9w4.png" alt="Messages per month, ChatGPT to Claude, browser to terminal" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usage drifted from browser to terminal over time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where the history lives
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ChatGPT (browser)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Settings&lt;/strong&gt; from the account icon (top right)&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Data controls&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Export data&lt;/strong&gt; → confirm&lt;/li&gt;
&lt;li&gt;A link arrives by email; download the zip from there&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Claude (browser)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Settings&lt;/strong&gt; from your name (bottom left)&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Privacy&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Hit &lt;strong&gt;Export data&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A link arrives by email; download the zip from there&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Neither one is instant — you wait a bit for the email.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminal (Claude Code, Codex CLI)
&lt;/h3&gt;

&lt;p&gt;No request needed. The logs are already on your machine — just copy them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Claude Code&lt;/span&gt;
~/.claude/projects/&amp;lt;per-project&amp;gt;/&lt;span class="k"&gt;*&lt;/span&gt;.jsonl

&lt;span class="c"&gt;# Codex CLI&lt;/span&gt;
~/.codex/sessions/&amp;lt;year&amp;gt;/&amp;lt;month&amp;gt;/&amp;lt;day&amp;gt;/&lt;span class="k"&gt;*&lt;/span&gt;.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What you get from each
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Browser export&lt;/th&gt;
&lt;th&gt;Terminal logs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;How to get it&lt;/td&gt;
&lt;td&gt;Request, wait for email&lt;/td&gt;
&lt;td&gt;Just copy the files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conversation text&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image / attachment files&lt;/td&gt;
&lt;td&gt;Yes (563 for me)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared-link conversations&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Project settings &amp;amp; docs&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Record of what the AI actually did&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note that &lt;strong&gt;the browser export does not contain your terminal history&lt;/strong&gt;, and vice versa. If you work across two machines, collect from both.&lt;/p&gt;




&lt;h2&gt;
  
  
  Audit 1: what I use it for
&lt;/h2&gt;

&lt;p&gt;First, what was I actually using AI for? I had qwen2.5 read each conversation and tag it one by one ("this is research," "this is coding").&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu6g7zeh8qrs4phwpaotm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu6g7zeh8qrs4phwpaotm.png" alt="What I used AI for, and how browser vs terminal differ" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The big ones were research &amp;amp; learning (291), writing &amp;amp; editing (236), coding (193), and setup &amp;amp; troubleshooting (151) — two-thirds of everything.&lt;/p&gt;

&lt;p&gt;Split by tool, it separates cleanly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Browser&lt;br&gt;1,267 convos&lt;/th&gt;
&lt;th&gt;Terminal&lt;br&gt;75 convos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Coding&lt;/td&gt;
&lt;td&gt;12.0%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;54.7%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup &amp;amp; troubleshooting&lt;/td&gt;
&lt;td&gt;10.9%&lt;/td&gt;
&lt;td&gt;17.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Research &amp;amp; learning&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;22.7%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Writing &amp;amp; editing&lt;/td&gt;
&lt;td&gt;18.1%&lt;/td&gt;
&lt;td&gt;9.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Terminal is 70% code-related; browser is 40% research and writing. &lt;strong&gt;The topics themselves split neatly between the two tools.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One caveat: the terminal side is only 75 conversations, so read it as a rough tendency, not a precise number. (Why so few? See "Not keeping work data in the first place" below.)&lt;/p&gt;




&lt;h2&gt;
  
  
  Audit 2: how I ask
&lt;/h2&gt;

&lt;p&gt;Next, how I phrase requests. I counted phrasing patterns as a proxy for care. The yardstick is Anthropic's &lt;strong&gt;AI Fluency Framework&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhd8bx4vae7zmczibuga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxhd8bx4vae7zmczibuga.png" alt="Browser vs terminal on how I phrase requests; terminal is higher on all four" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phrasing I counted&lt;/th&gt;
&lt;th&gt;Browser&lt;/th&gt;
&lt;th&gt;Terminal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Specify steps or format&lt;/td&gt;
&lt;td&gt;21%&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reject the output&lt;/td&gt;
&lt;td&gt;11%&lt;/td&gt;
&lt;td&gt;22%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ask for the reasoning&lt;/td&gt;
&lt;td&gt;8%&lt;/td&gt;
&lt;td&gt;24%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ask it to verify&lt;/td&gt;
&lt;td&gt;6%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;35%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;In the terminal, my instructions are much more detailed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(A fair reading: the terminal is where I do code work, and code work naturally invites step-by-step instructions and verification — so this may be a difference in &lt;em&gt;task&lt;/em&gt;, not in skill.)&lt;/p&gt;




&lt;h2&gt;
  
  
  Audit 3: which features I use
&lt;/h2&gt;

&lt;p&gt;The terminal logs record what the AI actually &lt;em&gt;did&lt;/em&gt;. Here's the operation history:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Most-used operations&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bash (run a command)&lt;/td&gt;
&lt;td&gt;4,053&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit (change a file)&lt;/td&gt;
&lt;td&gt;2,844&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read (read a file)&lt;/td&gt;
&lt;td&gt;2,443&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PowerShell&lt;/td&gt;
&lt;td&gt;1,001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write (create a file)&lt;/td&gt;
&lt;td&gt;612&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSearch&lt;/td&gt;
&lt;td&gt;460&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So the reality is: &lt;strong&gt;read, edit, run a command.&lt;/strong&gt; Nothing fancy.&lt;/p&gt;

&lt;p&gt;And here's how often I reached for the fancier stuff. Turns out I barely write my own skills...!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Usage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agents (the AI spawns helpers)&lt;/td&gt;
&lt;td&gt;78 times, 5,542 helper messages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP (connect to outside services)&lt;/td&gt;
&lt;td&gt;80 times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skills (built-in)&lt;/td&gt;
&lt;td&gt;6 times&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skills (my own)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Plan mode (approve a plan before it runs)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1 time&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/model&lt;/code&gt; (switch model)&lt;/td&gt;
&lt;td&gt;82 times&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Agents and MCP I already lean on. Skills and plan mode? Almost untouched.&lt;/p&gt;




&lt;h2&gt;
  
  
  The easy wins
&lt;/h2&gt;

&lt;p&gt;Three obvious places to improve:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Turn routine work into a Skill.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Zero of my own. My article pre-publish checklist runs the same way every time — I'd rather call it by name than re-ask by hand each time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use plan mode before big jobs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once in 17 months. I keep course-correcting mid-run; I'd rather see the plan first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Move all coding into the terminal.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;12.0% of it still happens in the browser, where the AI can't touch files directly — so I waste round-trips copy-pasting.&lt;/p&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I counted, and what I left out
&lt;/h3&gt;

&lt;p&gt;I counted only human↔AI text exchanges. I dropped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;agent-*.jsonl&lt;/code&gt; / &lt;code&gt;journal.jsonl&lt;/code&gt; — internal work logs the AI keeps&lt;/li&gt;
&lt;li&gt;Sub-agent (AI helper) messages, 5,542 of them — not typed by a human&lt;/li&gt;
&lt;li&gt;Auto-inserted text like &lt;code&gt;&amp;lt;system-reminder&amp;gt;&lt;/code&gt; — same reason&lt;/li&gt;
&lt;li&gt;Image/attachment contents (563 &lt;code&gt;.dat&lt;/code&gt; files) — text only this time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;One thing I missed:&lt;/strong&gt; Claude's &lt;code&gt;design_chats&lt;/code&gt; (3 conversations) got skipped because my loader only reads &lt;code&gt;conversations.json&lt;/code&gt;. It's just one message, so the numbers don't move — but I can't claim I read the &lt;em&gt;entire&lt;/em&gt; export.&lt;/p&gt;

&lt;h3&gt;
  
  
  What counts as a "phrasing"
&lt;/h3&gt;

&lt;p&gt;I picked these up with regular expressions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What I counted&lt;/th&gt;
&lt;th&gt;Example words (Japanese source)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Specify steps or format&lt;/td&gt;
&lt;td&gt;first / next / finally / "in a table" / bullet points / JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reject the output&lt;/td&gt;
&lt;td&gt;wrong / not that / that's off / not working&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ask for the reasoning&lt;/td&gt;
&lt;td&gt;really? / is that right / evidence / source / why&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ask it to verify&lt;/td&gt;
&lt;td&gt;test / run it / verify / double-check / reproduce&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It's counting surface phrasing, not actual competence — treat it as a rough proxy. The comparison used conversations from May 2026 onward, where I use both tools: 348 browser vs 102 terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not keeping work data in the first place
&lt;/h3&gt;

&lt;p&gt;Nearly half the history was work. That isn't even really &lt;em&gt;my&lt;/em&gt; data — it belongs to the other party.&lt;/p&gt;

&lt;p&gt;At load time I classify by folder name; for work, I throw away the body and keep only a character count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# keep the body only when it's confirmed personal
&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;personal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;web&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The classification keywords are literally client/partner names, so they don't live in the code — they're read from a config file that never enters Git. &lt;strong&gt;The classifier itself is more sensitive than the data it classifies&lt;/strong&gt; — an obvious point I only noticed during the pre-publish check.&lt;/p&gt;

&lt;p&gt;Because of this design, I could only read 75 of the 12,530 terminal conversations. A design that protects me also trimmed my own analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  The measurement flipped three times
&lt;/h3&gt;

&lt;p&gt;My first pass showed every metric &lt;em&gt;dropping&lt;/em&gt;. Read naively: "I got sloppy." But it was the denominator's fault.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;How I measured&lt;/th&gt;
&lt;th&gt;What it showed&lt;/th&gt;
&lt;th&gt;The problem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rate per message&lt;/td&gt;
&lt;td&gt;All metrics fall&lt;/td&gt;
&lt;td&gt;Shorter messages drag it down automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate per conversation&lt;/td&gt;
&lt;td&gt;Still falls&lt;/td&gt;
&lt;td&gt;Picking up the shifting browser/terminal mix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split browser vs terminal&lt;/td&gt;
&lt;td&gt;Terminal higher on everything&lt;/td&gt;
&lt;td&gt;← adopted this&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I couldn't compare past-me to present-me directly: the tools swapped underneath me, so a skill difference and a place difference get tangled together.&lt;/p&gt;

&lt;h3&gt;
  
  
  A junked experiment: blind-judging old vs new requests
&lt;/h3&gt;

&lt;p&gt;I hid the dates and had qwen2.5 compare an old request against a new one. Result: old won 10, new won 3. But it was browser-vs-browser, so I was really comparing "browser when I used it seriously" against "browser after it became an afterthought." It says nothing about whether I improved. (I judged each pair twice with the order flipped, counting a win only when both agreed — a fix for the position bias I found in the Day 14 cat-meow quiz.)&lt;/p&gt;

&lt;p&gt;Speed notes, since I got stuck:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Snag&lt;/th&gt;
&lt;th&gt;What happened&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Big model won't fit&lt;/td&gt;
&lt;td&gt;qwen2.5 72B: only 39.2 of 62.9 GB on the GPU → 7 min per judgment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model switching&lt;/td&gt;
&lt;td&gt;The previous model lingers; timeouts right after a switch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt length&lt;/td&gt;
&lt;td&gt;621 chars = 8s, 918 chars = 22s, 1,500 chars didn't finish in 60s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Switching to 32B (19 GB) fit entirely on the GPU → a few seconds each. Fitting or not fitting changes the order of magnitude. And the scoring isn't very reliable: of 25 browser-vs-browser pairs only 16 were usable, and for browser-old vs terminal-new, 17 of 25 timed out. No cloud API was used, so this analysis cost $0 (electricity aside).&lt;/p&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The AI Fluency Framework — Rick Dakan, Joseph Feller, and Anthropic (CC BY-NC-SA 4.0): &lt;a href="https://aifluencyframework.org/" rel="noopener noreferrer"&gt;https://aifluencyframework.org/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;Line up 17 months and you can see exactly what you were doing each month. Re-uploading all of that somewhere to analyze it feels like a bit much. Keeping it on my own machine is well suited to moments like this.&lt;/p&gt;

&lt;p&gt;Soon, I'd like to build a Skill of my own.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>productivity</category>
    </item>
    <item>
      <title>[Day 16] I made a theme song for my cat — lyrics, melody, and singing voice, all AI, all local</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Sat, 18 Jul 2026 14:34:28 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-16-i-made-a-theme-song-for-my-cat-lyrics-melody-and-singing-voice-all-ai-all-local-c3g</link>
      <guid>https://dev.to/peppercorn_llm/day-16-i-made-a-theme-song-for-my-cat-lyrics-melody-and-singing-voice-all-ai-all-local-c3g</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 16!&lt;/p&gt;

&lt;p&gt;Today's experiment: &lt;strong&gt;make a theme song for my family's cat&lt;/strong&gt; — and see if it actually feels like &lt;em&gt;their&lt;/em&gt; song, not a generic AI tune.&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;ACE-Step 1.5&lt;/strong&gt;, a local music-generation AI (think "a Suno you can run at home"). It produced the whole package: lyrics, melody, and a singing voice. Everything here was generated locally on my own machine.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: DGX Spark (my home AI machine) / ACE-Step 1.5 XL (music-generation AI).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Today's experiment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I wanted to do
&lt;/h3&gt;

&lt;p&gt;One theme song for my cat (Japanese vocals, ~3 minutes). Plus a few background tracks on the side, to measure how fast generation really is.&lt;/p&gt;

&lt;h3&gt;
  
  
  The approach
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;First, the AI &lt;strong&gt;interviews me about my cat&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It &lt;strong&gt;turns my answers into lyrics&lt;/strong&gt; (there's a "template" for which answer goes where)&lt;/li&gt;
&lt;li&gt;Hand the lyrics and a style prompt to ACE-Step 1.5 to &lt;strong&gt;generate the song&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The goal
&lt;/h3&gt;

&lt;p&gt;Not "huh, the AI made something," but &lt;strong&gt;a song I'd actually recognize as my cat's&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  STEP 1: the AI interviewed me about my cat
&lt;/h2&gt;

&lt;p&gt;Writing the lyrics started with me answering six questions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;My answer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;What do you call them in the song?&lt;/td&gt;
&lt;td&gt;"Our Nekko" (our little cat)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Personality in a word?&lt;/td&gt;
&lt;td&gt;Super tsundere, super timid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Favorite gesture or habit?&lt;/td&gt;
&lt;td&gt;Getting the base of their tail tapped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;One memorable episode?&lt;/td&gt;
&lt;td&gt;It takes at least six months to truly bond&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;How do you feel about them?&lt;/td&gt;
&lt;td&gt;Calm — when they're nearby&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Any song requests?&lt;/td&gt;
&lt;td&gt;Bright and upbeat, female vocal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Tsundere"&lt;/strong&gt; = prickly on the outside, secretly sweet on the inside. A very cat thing.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  STEP 2: the template that turns answers into lyrics
&lt;/h2&gt;

&lt;p&gt;Each answer lands in a fixed place in the song.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Interview answer&lt;/th&gt;
&lt;th&gt;Where it goes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The name&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Chorus&lt;/strong&gt; (repeated in the catchiest spot)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Personality&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Verse 1&lt;/strong&gt; (introduce the character with everyday scenes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Habit&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Verse 2&lt;/strong&gt; (sharpen the picture with specifics)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Bridge&lt;/strong&gt; (the emotional beat late in the song)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feeling&lt;/td&gt;
&lt;td&gt;The chorus's tone + the overall mood&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Song request&lt;/td&gt;
&lt;td&gt;Not lyrics — the &lt;strong&gt;style prompt&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With that template, my cat's chorus came out like this (Japanese, with a rough English gloss):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uchi-no-Nekko wa tsun-tsun-tsundere      (Our Nekko is tsun-tsun-tsundere)
Kokoro no tobira wa katai kedo           (The door to their heart stays shut, but)
Kiiroi hitomi de chiratto ichibetsu      (Those yellow eyes shoot one quick glance)
Dere wa kibun de nen ni suukai           (The sweet side? A few times a year, if you're lucky)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  STEP 3: generate. A 3-minute Japanese-vocal song
&lt;/h2&gt;

&lt;p&gt;Hand ACE-Step 1.5 XL the lyrics and a style prompt (upbeat J-pop, female vocal, Japanese), and out came a &lt;strong&gt;full 3-minute song with Japanese singing&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Speed: the audio is 10 seconds, but "composing" takes 8 minutes
&lt;/h3&gt;

&lt;p&gt;The interesting part was the time breakdown.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What I made&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;BGM (90s, no vocals) ×4&lt;/td&gt;
&lt;td&gt;quick&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;40s total&lt;/strong&gt; (~10s each)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Theme song (3min, vocals)&lt;/td&gt;
&lt;td&gt;quick&lt;/td&gt;
&lt;td&gt;~10–15s each&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Theme song (3min, vocals)&lt;/td&gt;
&lt;td&gt;with composition planner&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~8 min&lt;/strong&gt; (first run ~23 min)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's the "composition planner"?&lt;/strong&gt; = the language model (LM) built into ACE-Step 1.5. It thinks through the song's blueprint (structure, metadata) &lt;em&gt;before&lt;/em&gt; rendering audio. Better quality, but the thinking costs time.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Bonus: I made an MV too
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/gZaiTgSVTJU"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;How it's built: &lt;strong&gt;Whisper&lt;/strong&gt; transcribes the lyric timings → an &lt;strong&gt;image AI&lt;/strong&gt; (AnythingV5) makes a character and backgrounds → a &lt;strong&gt;video AI&lt;/strong&gt; (LTX-2.3) animates the character → &lt;strong&gt;rembg&lt;/strong&gt; cuts it out and composites it onto the background with subtitles (finer steps in the fold below).&lt;/p&gt;

&lt;p&gt;Honestly, the video came out pretty cursed — the lower body suddenly morphs into a tail, the eyes go a little feral — so it's mildly unsettling. That's on the "improve later" list.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The slow part isn't the sound, it's the thinking&lt;/strong&gt;: the audio itself renders in ~10s; the long wait is the AI planning the song's structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Old tools converged&lt;/strong&gt;: anime-style image (Day 11) + Whisper (Day 14) + video generation (Day 15) came together into a single MV&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;p&gt;:::details Environment and models&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Machine: DGX Spark (128GB unified memory)&lt;/li&gt;
&lt;li&gt;ACE-Step 1.5: set up from the official repo with &lt;code&gt;uv&lt;/code&gt;. &lt;strong&gt;DGX Spark (ARM64 + CUDA 13) is listed as an officially supported target&lt;/strong&gt;, and it just ran&lt;/li&gt;
&lt;li&gt;Model setup: DiT is &lt;code&gt;acestep-v15-xl-turbo&lt;/code&gt; (4B, 8 steps), planner LM is the 4B version. ~36GB of downloads total&lt;/li&gt;
&lt;li&gt;Peak memory during generation ~27GB. Generated via the REST API server (easier to reproduce)&lt;/li&gt;
&lt;li&gt;MV side: ComfyUI (LTX-2.3 22B distilled fp8) + AnythingV5 (character &amp;amp; backgrounds) + rembg 2.0.76 (cutout, anime model isnet-anime) + Whisper large-v3 (timings) + ffmpeg (assembly)
:::&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;:::details Full lyrics and the style prompt&lt;br&gt;
Style prompt (Caption):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upbeat J-pop, energetic and heartwarming, female vocal, bright synth,
acoustic guitar, catchy chorus, 128 bpm, Japanese lyrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lyrics are passed with structural tags like &lt;code&gt;[Verse]&lt;/code&gt; and &lt;code&gt;[Chorus]&lt;/code&gt; (the words are Japanese; the &lt;code&gt;（にゃー）&lt;/code&gt; bits are meow ad-libs sung as backing vocals):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Intro]
（にゃー）

[Verse 1]
目が合った瞬間 ぷいっとそっぽ向く（にゃっ）
呼んでも来ないのに 気づけばそばにいる
物音ひとつで ロケットダッシュ（にゃー！）
ビビリなくせに 顔は堂々

[Pre-Chorus]
ツンとすまして 知らんぷり
それでもしっぽは 正直もの（にゃ？）

[Chorus - catchy]
うちのネッコは ツンツンツンデレ（にゃにゃ！）
心の扉は かたいけど
黄色い瞳で ちらっと一瞥
デレは気分で 年に数回（にゃー）

[Verse 2]
撫でられるのは 好きじゃないくせに
しっぽの付け根を とんとん叩けば
目を細めて 喉を鳴らして
もっと続けてと 視線で命令（にゃっ）

[Bridge - emotional]
心が通じるまで 半年かかった
ゆっくりゆっくり 縮めた距離は
いまでは世界で いちばん近い
気づけば隣が 定位置になった

[Chorus - anthemic]
うちのネッコは ツンツンツンデレ（にゃにゃ！）
ビビリなところも ご愛嬌
とんとんのリズムで しっぽが揺れる
今日も我が家の 王様です（にゃー！）

[Outro - fade out]
うちのネッコ（にゃー）
うちのネッコ（にゃー にゃー）
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A tip from the official docs: put the fine-grained style control in the Caption, and keep the lyric tags simple.&lt;br&gt;
:::&lt;/p&gt;

&lt;p&gt;:::details How the MV was built (the finer steps)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses the intro through the second chorus (~70s). Per-line timings from Whisper large-v3 (since I already know the lyrics, a mis-hear here and there is fine — I only use the timestamps)&lt;/li&gt;
&lt;li&gt;20+ cuts. One lyric line = one cut, each assigned a clip whose motion fits the words&lt;/li&gt;
&lt;li&gt;The character image is a single frame: my "anime-fied cat" from Day 11, redrawn into a mascot with an image AI (AnythingV5). That's handed to the video AI (LTX-2.3) to animate. ~30s per clip; motion is described in plain requests ("turn away," "walk cycle," etc.)&lt;/li&gt;
&lt;li&gt;Cutout compositing is frame-by-frame: rembg (isnet-anime) cuts out the character → composite onto a slowly zooming/panning background → draw subtitles → re-encode at 24fps&lt;/li&gt;
&lt;li&gt;Keeping the character's scale &lt;strong&gt;fixed within a cut&lt;/strong&gt; mattered. Matching to the per-frame silhouette makes it shrink the instant it stretches (learned the hard way)
:::&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;:::details Gotchas&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The dash comes last&lt;/strong&gt;: when I asked LTX-2.3 to "suddenly bolt away," the motion tended to land in the clip's final 0.5s. Worked around it by shifting the segment I use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feed the input image in the aspect ratio you want out&lt;/strong&gt;: at first I fed a portrait (512×768) character image into a landscape (768×512) generation, and every clip came out as an upper-body zoom that cut off the ears. Rebuilt the input as a landscape full-body image to fix it. Video AIs inherit the input image's composition quite strongly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The planner may have been running slower than it should&lt;/strong&gt;: digging through the logs, the LM's fast-execution component (vLLM) seems to have failed to compile due to a missing &lt;code&gt;Python.h&lt;/code&gt;, so it may have quietly fallen back to a slow path (I didn't fully chase down the cause on Day 16). I hit the same root cause on Day 15 (&lt;code&gt;python3.12-dev&lt;/code&gt; not installed) — could be a recurring Spark gotcha
:::&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;:::details License notes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ACE-Step 1.5&lt;/strong&gt;: code and weights both MIT. Commercial use OK&lt;/li&gt;
&lt;li&gt;Planner LM (4B, Qwen3-4B based): also MIT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The generated music is explicitly cleared for commercial use&lt;/strong&gt; in the official docs (training data is licensed + royalty-free + synthetic)&lt;/li&gt;
&lt;li&gt;MV-side tools (LTX-2.3, AnythingV5, rembg, Whisper) are the ones I already vetted on Days 11–15
:::&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ace-step/ACE-Step-1.5" rel="noopener noreferrer"&gt;ACE-Step 1.5 (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://huggingface.co/ACE-Step/acestep-v15-xl-turbo" rel="noopener noreferrer"&gt;ACE-Step/acestep-v15-xl-turbo (Hugging Face)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;Lyrics, melody, singing, and a music video — all AI, all on my own machine. See you next time!&lt;br&gt;
Thanks for reading!&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>music</category>
    </item>
    <item>
      <title>[Day 15] A cat photo became a video — with a meow. Two local video AIs compared: 30s vs 475s</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Mon, 13 Jul 2026 06:14:04 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-15-a-cat-photo-became-a-video-with-a-meow-two-local-video-ais-compared-30s-vs-475s-g70</link>
      <guid>https://dev.to/peppercorn_llm/day-15-a-cat-photo-became-a-video-with-a-meow-two-local-video-ais-compared-30s-vs-475s-g70</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 15!&lt;/p&gt;

&lt;p&gt;Today's experiment: &lt;strong&gt;turn one photo of my family's cat into a video that moves — and meows.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An image-to-video AI takes a single photo and imagines how the scene continues. I ran two of them and compared the results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: DGX Spark (my home AI machine) / two local video AIs (LTX-2.3 and Wan 2.2) / one photo of my family's cat.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Today's experiment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I wanted to find out
&lt;/h3&gt;

&lt;p&gt;Give both AIs the same cat photo and the same request — "look at the camera and meow once, about 4–5 seconds" — and compare them.&lt;/p&gt;

&lt;h3&gt;
  
  
  The two models
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wan 2.2&lt;/strong&gt;: a well-established favorite for local video. Video only, &lt;strong&gt;no audio&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LTX-2.3&lt;/strong&gt;: a newer model (March 2026) that generates &lt;strong&gt;video and audio together in one pass&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Same photo, same kind of prompt. Measured: &lt;strong&gt;generation time / memory / quality / sound&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The goal
&lt;/h3&gt;

&lt;p&gt;Decide which one to use when — with actual numbers from my own machine, not vibes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The result first: 30 seconds vs 475 seconds
&lt;/h2&gt;

&lt;p&gt;For a ~4–5 second video, LTX-2.3 took &lt;strong&gt;30 seconds&lt;/strong&gt;. Wan 2.2 took &lt;strong&gt;475 seconds&lt;/strong&gt;. Roughly a 16x gap.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvq4p38i2h8rc1wxof6gz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvq4p38i2h8rc1wxof6gz.png" alt="Generation time for one cat photo to a 4-5s video: Wan 2.2 standard 475s, with speed LoRA 70s, LTX-2.3 30s with audio" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's a "step"?&lt;/strong&gt; The number of refinement passes the AI makes while drawing the video. More steps = more careful but slower.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Time wasn't the only difference, though. Here is each result in turn.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wan 2.2 — nearly photoreal, but 8 minutes per video
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F74sxomq74xa2s7u2gojk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F74sxomq74xa2s7u2gojk.gif" alt="Wan 2.2 result: the cat opens its mouth and meows, nearly photoreal" width="300" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wan 2.2's output (475s, silent).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fur, markings, and face are &lt;strong&gt;almost indistinguishable from the real photo&lt;/strong&gt;, and it meows exactly as asked. But one video takes &lt;strong&gt;475 seconds&lt;/strong&gt; (~8 minutes), with &lt;strong&gt;no sound&lt;/strong&gt; (by design).&lt;/p&gt;

&lt;p&gt;A speed-up add-on cut it to &lt;strong&gt;70 seconds&lt;/strong&gt;, at the cost of tamer motion — more of a tongue flick than a proper meow.&lt;/p&gt;




&lt;h2&gt;
  
  
  LTX-2.3 — 30 seconds, and it came with a meow
&lt;/h2&gt;

&lt;p&gt;Here is LTX-2.3's output, sound included (volume on 🔊):&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/yjT-xcIB518"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Done in &lt;strong&gt;30 seconds&lt;/strong&gt; — and along with the video, it generated &lt;strong&gt;an audio track with actual meows&lt;/strong&gt;. I asked for one meow; it enthusiastically gave two, short cat-like "myah" sounds roughly in sync with the mouth. (And it sounds startlingly like my family cat's real meow.)&lt;/p&gt;

&lt;p&gt;Image quality looks about the same as Wan's on screen. The difference is in the motion: Wan moved more, and more realistically; LTX was a bit more subdued.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fix83k9rxd86m55tee52e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fix83k9rxd86m55tee52e.png" alt="One frame from each video generated from the same photo: Wan 2.2 on the left, LTX-2.3 on the right" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: give it the first and last frame, and you can design the camera work
&lt;/h2&gt;

&lt;p&gt;LTX-2.3 can take a &lt;strong&gt;first frame and a last frame, and fill in everything between&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I gave it the wide shot as the first frame, and a face close-up (a crop of the same photo) as the last.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgrxm02ss18kj3ifwabjx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgrxm02ss18kj3ifwabjx.png" alt="First frame: wide shot. Last frame: face close-up. The model filled in a zoom with a meow in the middle" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5hjmeh1suaryl6busdoz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5hjmeh1suaryl6busdoz.gif" alt="The generated video zooms from wide shot to close-up with a meow along the way" width="300" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Generated in 35 seconds.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The video starts wide, meows while zooming in, and ends on the close-up I specified.&lt;/p&gt;




&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;Peak memory&lt;/th&gt;
&lt;th&gt;Audio&lt;/th&gt;
&lt;th&gt;Quality impression&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wan 2.2 (standard)&lt;/td&gt;
&lt;td&gt;475s&lt;/td&gt;
&lt;td&gt;~49GB&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;near-photoreal, faithful motion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wan 2.2 + speed LoRA&lt;/td&gt;
&lt;td&gt;70s&lt;/td&gt;
&lt;td&gt;~46GB&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;clean but tamer motion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LTX-2.3&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;30s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~57GB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;on par with Wan; tamer motion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LTX-2.3 (designed zoom)&lt;/td&gt;
&lt;td&gt;35s&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;same as above&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Resolutions and frame counts follow each model's recommended settings, so this isn't a strictly identical-conditions benchmark (details below).&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Distinct characters&lt;/strong&gt;: Wan for faithful motion, LTX for speed and sound. Not "which is better" but "which for what"&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Specifying the first and last frame let me design the camera work&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The time gap is really a retry-count gap&lt;/strong&gt;: at 30 seconds, "one more try" is easy&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Environment and models
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Machine: DGX Spark (128GB unified memory)&lt;/li&gt;
&lt;li&gt;ComfyUI v0.24.0 (native LTX-2.3 support) + Lightricks' official custom nodes&lt;/li&gt;
&lt;li&gt;Both models in their fp8 (weight-reduced) versions; ~91GB of downloads total

&lt;ul&gt;
&lt;li&gt;Wan 2.2 I2V-A14B (high-noise/low-noise pair, 14GB each) + its text encoder&lt;/li&gt;
&lt;li&gt;LTX-2.3 22B distilled (28GB) + Gemma 3 12B as its text encoder (13GB)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The speed add-on for Wan is the lightx2v 4-step LoRA&lt;/li&gt;
&lt;li&gt;Attention backend unified on PyTorch SDPA for both models&lt;/li&gt;
&lt;li&gt;Runs were headless ComfyUI (API calls) driven by a small runner script that logs time and memory for every run&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comparison-condition fine print
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Wan 2.2: 480×640, 81 frames, 16fps (~5.1s), 20 steps&lt;/li&gt;
&lt;li&gt;LTX-2.3: 512×768, 97 frames, 24fps (~4.0s), 8 steps&lt;/li&gt;
&lt;li&gt;Each model ran its official template's representative settings, so resolution/frames/steps differ — it's a comparison of each model's everyday settings&lt;/li&gt;
&lt;li&gt;Per-step time: ~23s for Wan, ~2.6s for LTX&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The one gotcha I hit (LTX)
&lt;/h3&gt;

&lt;p&gt;My hand-built workflow crashed inside an LTX helper node (LTXVCropGuides).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cause: with audio+video generation, the latent is a special combined tensor (a NestedTensor), and this node calls an operation it doesn't support&lt;/li&gt;
&lt;li&gt;Fix #1: for plain image-to-video, the node isn't needed at all — removing it solved the crash&lt;/li&gt;
&lt;li&gt;Fix #2: for the first/last-frame trick the node &lt;em&gt;is&lt;/em&gt; required, so I moved it to run &lt;strong&gt;after&lt;/strong&gt; the audio/video split, where the tensor is ordinary again&lt;/li&gt;
&lt;li&gt;The known audio-VAE NaN bug I had braced for never appeared&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  License notes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wan 2.2&lt;/strong&gt;: Apache 2.0. Commercial use OK, generated content is yours&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LTX-2.3&lt;/strong&gt;: LTX-2 Community License. Free commercial use under $10M annual revenue. &lt;strong&gt;Disclosing that content is AI-generated is mandatory&lt;/strong&gt;. Also has an unusual remote-access restriction clause&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3&lt;/strong&gt; (LTX's text encoder): Gemma Terms of Use. Commercial use OK, outputs belong to the user, subject to the prohibited-use policy&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Lightricks/LTX-2" rel="noopener noreferrer"&gt;Lightricks LTX-2 (GitHub)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://huggingface.co/Wan-AI/Wan2.2-I2V-A14B" rel="noopener noreferrer"&gt;Wan-AI/Wan2.2-I2V-A14B (Hugging Face)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;One photo, and 30 seconds later my family's cat was meowing on screen. See you next time!&lt;br&gt;
Thanks for reading!&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>[Day 14] I quizzed an AI on cat meows. It scored worse than random guessing</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Thu, 09 Jul 2026 04:57:52 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-14-i-quizzed-an-ai-on-cat-meows-it-scored-worse-than-random-guessing-42j5</link>
      <guid>https://dev.to/peppercorn_llm/day-14-i-quizzed-an-ai-on-cat-meows-it-scored-worse-than-random-guessing-42j5</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 14!&lt;/p&gt;

&lt;p&gt;Today's experiment: &lt;strong&gt;play cat meows to an AI and have it guess what the cat wants.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I really wanted to use my own cat's meows, but couldn't get recordings — so I used a public research dataset (meows from 21 cats).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: DGX Spark (my home AI machine) / Whisper (speech-to-text AI) / Qwen2-Audio (an AI that can listen to audio directly) / 440 cat meows (public dataset).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Today's experiment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I wanted to find out
&lt;/h3&gt;

&lt;p&gt;Can an AI tell how a cat feels, from its meow alone?&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A research dataset of meows with situation labels (21 cats, 440 clips)&lt;/li&gt;
&lt;li&gt;Hide the labels → 90-question 3-choice quiz → grade it&lt;/li&gt;
&lt;li&gt;Detour: see what Whisper makes of raw meows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The goal
&lt;/h3&gt;

&lt;p&gt;Find out, by experiment, whether a general-purpose audio AI can understand cat voices — judged by an actual score, not a feeling.&lt;/p&gt;




&lt;h2&gt;
  
  
  Result first: this AI could not read cat feelings
&lt;/h2&gt;

&lt;p&gt;On a 3-choice quiz, its accuracy was &lt;strong&gt;23.3%&lt;/strong&gt; — below random guessing (33.3%).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5zqe7utvfb7hs4h8d4a3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5zqe7utvfb7hs4h8d4a3.png" alt="3-choice meow quiz accuracy. The specialized 2019 ML model got 95.9%, Qwen2-Audio got 23.3% and 32.2%"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I dug in, it turned out the AI &lt;strong&gt;wasn't really listening to the meows in the first place&lt;/strong&gt;. Here's what happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's material: 440 meows from 21 cats
&lt;/h2&gt;

&lt;p&gt;I used &lt;strong&gt;CatMeows&lt;/strong&gt;, a research dataset of cat vocalizations (credit at the end of this post). Every meow comes with an &lt;strong&gt;answer label&lt;/strong&gt; — the situation it was recorded in.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Label&lt;/th&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Brushing&lt;/td&gt;
&lt;td&gt;Being brushed by the owner&lt;/td&gt;
&lt;td&gt;127&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Waiting for food&lt;/td&gt;
&lt;td&gt;Food is being prepared&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;td&gt;Left alone in an unfamiliar room&lt;/td&gt;
&lt;td&gt;221&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Experiment 1: first, a speech-to-text AI
&lt;/h2&gt;

&lt;p&gt;First, a detour: what happens if you hand raw cat meows to &lt;strong&gt;Whisper&lt;/strong&gt;, the speech-to-text AI?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flrikiizrkbfyr7yue93w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flrikiizrkbfyr7yue93w.png" alt="Waveform of a cat meow. Whisper transcribed it as "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Japanese mode, &lt;strong&gt;10 of the 12 meows&lt;/strong&gt; came back as 「ご視聴ありがとうございました」("Thank you for watching!") — plus one 「チャンネル登録をお願いいたします。」(&lt;strong&gt;"Please subscribe to my channel."&lt;/strong&gt;)&lt;/p&gt;

&lt;p&gt;Whisper is trained on subtitled video audio, so unrecognizable sounds tend to come back as the stock phrases that end videos.&lt;/p&gt;




&lt;h2&gt;
  
  
  Experiment 2: a 90-question quiz for the AI
&lt;/h2&gt;

&lt;p&gt;Next, I handed meows one at a time to &lt;strong&gt;Qwen2-Audio&lt;/strong&gt; (an AI that listens to audio directly) and asked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is a recording of a domestic cat meowing.&lt;br&gt;
In which situation was this meow most likely recorded?&lt;br&gt;
(A) The cat is being brushed by its owner.&lt;br&gt;
(B) The cat is waiting for food.&lt;br&gt;
(C) The cat is isolated alone in an unfamiliar room.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;90 questions total — 30 meows from each situation. Random guessing would score 33.3%.&lt;/p&gt;

&lt;p&gt;The result: &lt;strong&gt;23.3% (21 out of 90)&lt;/strong&gt;. It lost to random guessing.&lt;/p&gt;

&lt;p&gt;Here's the per-situation breakdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Correct&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Brushing&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0 / 30&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Waiting for food&lt;/td&gt;
&lt;td&gt;9 / 30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;td&gt;12 / 30&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Brushing: &lt;strong&gt;zero&lt;/strong&gt;. The AI never once picked "(A) brushing" in all 90 questions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Experiment 3: shuffle the option order
&lt;/h2&gt;

&lt;p&gt;"Never picks A" is odd. So I checked: &lt;strong&gt;same meows, same question, only the option order swapped&lt;/strong&gt; — another 90 questions.&lt;/p&gt;

&lt;p&gt;If the AI answers by listening, changing the order shouldn't change its answers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc87g8yl4vfbbhvn6buhi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc87g8yl4vfbbhvn6buhi.png" alt="Which option the AI picked. Run 1: B 40 times, C 50 times. Run 2: B 89 times, C once. Option A: zero in both runs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In fact, the answers flipped completely.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;The AI's answers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Before the swap&lt;/td&gt;
&lt;td&gt;"isolation" ×50 / "food" ×40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;After the swap&lt;/td&gt;
&lt;td&gt;almost all "food" (×89)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Option A (first)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0&lt;/strong&gt; in both runs (0 out of 180)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The AI was answering by option order, not by the meow.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(The post-swap 32.2% accuracy only looks better because answering "food" every time gets exactly the food questions right.)&lt;/p&gt;




&lt;h2&gt;
  
  
  Meanwhile, a meow-only AI scored 96%
&lt;/h2&gt;

&lt;p&gt;The research team behind this dataset built a &lt;strong&gt;purpose-built meow classifier&lt;/strong&gt; (2019) that scores &lt;strong&gt;95.9%&lt;/strong&gt; on the same 3-way task (trained on this data, so not the same conditions as my zero-shot run).&lt;/p&gt;

&lt;p&gt;General-purpose audio AI seems to be &lt;strong&gt;strong at words, still weak at what non-word sounds mean&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quizzes get gamed&lt;/strong&gt;: an audio LLM may answer by option position instead of listening. Shuffle the options and rerun to catch it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't trust accuracy alone&lt;/strong&gt;: the 32.2% run was all-in on one answer. Check the answer distribution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whisper hallucinates&lt;/strong&gt;: non-speech sounds come back as stock phrases from its training data ("Thank you for watching!")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Niche tasks want specialists&lt;/strong&gt;: for reading meows, a purpose-built model is the right tool&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Models and dataset
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Speech-to-text: openai/whisper-large-v3-turbo (MIT license)&lt;/li&gt;
&lt;li&gt;Quiz: Qwen/Qwen2-Audio-7B-Instruct (Apache 2.0), run locally via transformers, greedy decoding (do_sample=False) so answers are reproducible&lt;/li&gt;
&lt;li&gt;Dataset: CatMeows (CC BY 4.0). 21 cats, 440 clips, 8kHz mono. The first letter of each filename is the ground-truth label (B=brushing, F=food, I=isolation)&lt;/li&gt;
&lt;li&gt;Machine: DGX Spark. A 7B audio model fits in memory with plenty of room; a few seconds per question&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How I asked the quiz (prompt)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is a recording of a domestic cat meowing.
In which situation was this meow most likely recorded?
Choose exactly one:
(A) The cat is being brushed by its owner.
(B) The cat is waiting for food.
(C) The cat is isolated alone in an unfamiliar room.
Answer with only the single letter A, B, or C.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;30 clips per label, stratified sampling with a fixed random seed → 90 questions&lt;/li&gt;
&lt;li&gt;The control run swapped the wording of (A) and (C) only; everything else identical&lt;/li&gt;
&lt;li&gt;Grading: extract the first A/B/C that appears in the model's reply&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Environment notes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I reused an existing Python environment and added librosa for audio loading, which bumped numpy past what another library wanted (core stayed fine). Lesson re-learned: &lt;strong&gt;separate environments per experiment is the safer way&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The recordings are 8kHz (phone quality); the models expect 16kHz, so audio is resampled on load. Could that hurt? Maybe — but the specialized model hit 96% on the same 8kHz clips, so it's not much of an excuse&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Meow dataset: CatMeows: A Publicly-Available Dataset of Cat Vocalizations (Zenodo, DOI: &lt;a href="https://zenodo.org/records/4008297" rel="noopener noreferrer"&gt;10.5281/zenodo.4008297&lt;/a&gt;, CC BY 4.0)&lt;/li&gt;
&lt;li&gt;Original paper: Ntalampiras et al., "Automatic Classification of Cat Vocalizations Emitted in Different Contexts," Animals 9(8), MDPI, 2019 (the 95.9% figure is from this paper)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Outro
&lt;/h2&gt;

&lt;p&gt;I set out to have an AI listen to cats' feelings, and instead found an AI that answers by option order. The day it understands my own cat's meows still seems a way off.&lt;/p&gt;

&lt;p&gt;Next up: a completely different experiment. Thanks for reading!&lt;/p&gt;

&lt;p&gt;#100ExperimentsWithDGX #LocalLLM&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>[Day 13] I got a cat to "talk." The biggest wall: the AI couldn't recognize the cat's face</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Fri, 03 Jul 2026 07:06:10 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-13-i-got-a-cat-to-talk-the-biggest-wall-the-ai-couldnt-recognize-the-cats-face-1o8l</link>
      <guid>https://dev.to/peppercorn_llm/day-13-i-got-a-cat-to-talk-the-biggest-wall-the-ai-couldnt-recognize-the-cats-face-1o8l</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 13!&lt;/p&gt;

&lt;p&gt;Today's experiment: take &lt;strong&gt;a single cat image, lay human facial motion on top of it, and make a "talking cat."&lt;/strong&gt; It's the usual "talking avatar" idea, except I use a cat instead of my own face. The tool is &lt;strong&gt;LivePortrait&lt;/strong&gt; (still image + a "driving video" of motion → it transfers the video's expressions onto the still).&lt;/p&gt;

&lt;p&gt;The result: a &lt;strong&gt;cat that properly talks&lt;/strong&gt;. The hard part wasn't the animation — it was the step before it, &lt;strong&gt;getting the AI to recognize the cat's face&lt;/strong&gt;. Here's where it snagged, and how I got past it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: DGX Spark (my home AI machine) / LivePortrait / one cat image (AI-generated) / a driving video (ships with LivePortrait).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Result first: a talking cat
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4n1mxrj5y9wmoq6t4c6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4n1mxrj5y9wmoq6t4c6c.png" alt="The finished " width="512" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4s108df8tbm2ly7ehwni.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4s108df8tbm2ly7ehwni.gif" alt="Mouth and eyes both move — a properly talking cat (generated result, GIF)" width="400" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The mouth and eye movement from a human talking-video landed on the cat's face. But there were a few snags on the way here.&lt;/p&gt;




&lt;h2&gt;
  
  
  Snag #1: it won't recognize a "face" at all
&lt;/h2&gt;

&lt;p&gt;To make a cat talk, there's a first step: &lt;strong&gt;find where the face is in the image (the position of eyes, nose, mouth)&lt;/strong&gt; — the &lt;em&gt;face detector&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The tool I reached for first &lt;strong&gt;didn't have a single one installed&lt;/strong&gt;, so it stopped with an error every time. I added detectors and tried again, but the answer didn't change:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Detector I added&lt;/th&gt;
&lt;th&gt;Commercial use&lt;/th&gt;
&lt;th&gt;Recognized the cat's face?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MediaPipe&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;❌ no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;InsightFace&lt;/td&gt;
&lt;td&gt;Not allowed (non-commercial)&lt;/td&gt;
&lt;td&gt;❌ no&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;None could recognize the cat's face. They're not broken — they're all built to find &lt;strong&gt;human faces&lt;/strong&gt;, so a cat's face doesn't register as a "face."&lt;/p&gt;




&lt;h2&gt;
  
  
  Snag #2: why it couldn't recognize the face
&lt;/h2&gt;

&lt;p&gt;The "animal mode" of the tool I started with only swaps the &lt;strong&gt;motion part&lt;/strong&gt; for an animal version — &lt;strong&gt;the crucial "find the animal's face" detector was never bundled in&lt;/strong&gt;. All that's left is the human one.&lt;/p&gt;

&lt;p&gt;That was why work had stalled here last time, too. Not disk space, not the GPU — just a tool that couldn't look for an animal's face.&lt;/p&gt;




&lt;h2&gt;
  
  
  The fix: use the original tool, and skip the build
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;upstream (original) LivePortrait&lt;/strong&gt; does ship an animal-specific face detector, called &lt;strong&gt;XPose&lt;/strong&gt;. So I set it up in a separate folder and used that.&lt;/p&gt;

&lt;p&gt;The catch: XPose normally needs you to &lt;strong&gt;compile (build) a part on your own machine&lt;/strong&gt;, and on this new-generation machine there was no guarantee the build would go through. So, reading the code, I found a &lt;strong&gt;slower but no-build spare part&lt;/strong&gt; tucked inside. I rewrote three files to route to it, dodging compilation entirely. For a short clip, the slowness doesn't matter.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The exact files and edits are in "The details" at the bottom.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  It worked — but at first it just looked like the cat stuck its tongue out
&lt;/h2&gt;

&lt;p&gt;The detector ran, the cat's face was recognized, and a video generated. But the first result looked like the &lt;strong&gt;cat just gave a little tongue-out blep&lt;/strong&gt;. The expression transfer was clearly working — so why?&lt;/p&gt;

&lt;p&gt;The cause was the &lt;strong&gt;driving video&lt;/strong&gt; (= the input you feed the AI). My first one was a short "just open the mouth" sample — and if the reference only opens its mouth, the cat only opens its mouth. Swapping in a video of someone &lt;strong&gt;actually talking&lt;/strong&gt; gave me a cat whose eyes and mouth both moved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu0pld2xnnne4cgvgi1ab.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu0pld2xnnne4cgvgi1ab.gif" alt="Left: a " width="640" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The quality of the driving video pretty much decides the result.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's takeaway
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The hard part isn't the motion engine, it's &lt;strong&gt;recognizing the animal's face&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A tool's "animal support" can be &lt;strong&gt;a label with the actual part (the detector) missing&lt;/strong&gt;. When it won't run, tracking down which part is missing is the fast path.&lt;/li&gt;
&lt;li&gt;If you hit a "must compile" part on a too-new machine, &lt;strong&gt;look first for a no-build fallback route&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The quality of the result is mostly decided by &lt;strong&gt;the quality of the input (the driving motion)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  A note on licensing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The detectors that could recognize the cat's face (XPose / InsightFace) are both &lt;strong&gt;non-commercial&lt;/strong&gt; licenses. So I avoid commercial use of the footage itself, and this article keeps the focus on the method and the gotchas.&lt;/li&gt;
&lt;li&gt;The commercially-OK detector (MediaPipe) couldn't recognize the cat this time.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What was missing, and how it was solved
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The "animal mode" of the ComfyUI node I used first only swaps in the animal &lt;strong&gt;motion&lt;/strong&gt; model; the &lt;strong&gt;animal face detector (XPose) is not bundled&lt;/strong&gt;. Human detectors (InsightFace / MediaPipe / FaceAlignment) can't detect a cat's face, so it stops at &lt;code&gt;No face detected&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The fix: set up &lt;strong&gt;upstream KwaiVGI/LivePortrait&lt;/strong&gt; in a separate folder, fetch the official weight set (including &lt;code&gt;xpose.pth&lt;/code&gt;), and use &lt;code&gt;inference_animals.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The InsightFace and landmark models I already had could be reused.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The no-compile patch for XPose
&lt;/h3&gt;

&lt;p&gt;XPose is built to &lt;strong&gt;compile its own CUDA custom op&lt;/strong&gt; called &lt;code&gt;MultiScaleDeformableAttention&lt;/code&gt;. On the newest GPU/CUDA generation there's no guarantee that build succeeds, so I &lt;strong&gt;routed it to the bundled pure-PyTorch fallback&lt;/strong&gt; instead.&lt;/p&gt;

&lt;p&gt;Three files edited (under XPose's &lt;code&gt;ops/&lt;/code&gt;):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;functions/ms_deform_attn_func.py&lt;/code&gt;: wrap the compiled-version &lt;code&gt;import&lt;/code&gt; in try/except, set the flag to &lt;code&gt;False&lt;/code&gt; on failure.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;modules/ms_deform_attn.py&lt;/code&gt;: when that flag is &lt;code&gt;False&lt;/code&gt;, branch &lt;code&gt;forward&lt;/code&gt; through the pure-PyTorch &lt;code&gt;ms_deform_attn_core_pytorch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;(if needed) add &lt;code&gt;weights_only=False&lt;/code&gt; to the &lt;code&gt;torch.load&lt;/code&gt; in &lt;code&gt;animal_landmark_runner.py&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now animal detection runs with no compilation at all. It's slower, but for a short clip it's fine (one generation finished in ~8 seconds).&lt;/p&gt;

&lt;h3&gt;
  
  
  Environment gotchas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Each time I swapped detectors, the base library (numpy) version see-sawed (mediapipe wants numpy&amp;lt;2, insightface wants 2.x). The existing core (cv2/torch) survived, but &lt;strong&gt;the clean approach is to keep upstream LivePortrait in its own isolated environment&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;When stopping the server, killing by process name &lt;strong&gt;took out my own command too&lt;/strong&gt;. Stopping by port number was safe.&lt;/li&gt;
&lt;li&gt;Disk and GPU had plenty of headroom the whole time — not once was the snag a resource shortage.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Next up
&lt;/h2&gt;

&lt;p&gt;Next time I'm switching things up again with a different kind of experiment 🎬&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>[Day 12] I tried to build a line-art LoRA from video frames, and the characters' heads fused together</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Tue, 23 Jun 2026 00:41:38 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-12-i-tried-to-build-a-line-art-lora-from-video-frames-and-the-characters-heads-fused-3go</link>
      <guid>https://dev.to/peppercorn_llm/day-12-i-tried-to-build-a-line-art-lora-from-video-frames-and-the-characters-heads-fused-3go</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 12!&lt;/p&gt;

&lt;p&gt;This time I tried to take my own hand-drawn animation (a short video) and build a&lt;br&gt;
&lt;strong&gt;line-art LoRA that learns its art style and characters&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The plan was a little lazy, honestly. The usual way to train this is to prepare&lt;br&gt;
character stills one by one, by hand. But I thought:&lt;br&gt;
&lt;strong&gt;"I already have the video — why not just rip frames out of it and collect the&lt;br&gt;
training material the easy way?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Short version: &lt;strong&gt;the lines got clean, but the one thing that mattered — actually&lt;br&gt;
reproducing my characters — failed completely.&lt;/strong&gt; And the &lt;em&gt;reason&lt;/em&gt; it failed is what I&lt;br&gt;
actually took away from today.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: my home AI machine (DGX Spark) + a training tool (Kohya) + my own&lt;br&gt;
hand-drawn animation (two characters).&lt;br&gt;
Note: everything shown here is &lt;em&gt;LoRA-generated line art only&lt;/em&gt;. I'm not showing the&lt;br&gt;
source video itself or where it's published.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Result first: failure on the left, and the right is &lt;em&gt;also&lt;/em&gt; a failure
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzl409tzbll5078bcyf4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzl409tzbll5078bcyf4u.png" alt="Left: v1 trained on video frames (heads fuse). Right: v2 after rebuilding the dataset (clean lines, but a different person)" width="800" height="621"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Left is the first attempt. A second body grows upside-down out of the top of the head.&lt;br&gt;
Right is after I tracked down the causes and rebuilt the data — &lt;strong&gt;the lines came out&lt;br&gt;
clean&lt;/strong&gt;. But as you'll see, it's also a failure: it looks &lt;strong&gt;nothing like my original&lt;br&gt;
characters&lt;/strong&gt; — it's a totally different person.&lt;/p&gt;

&lt;p&gt;How can "the breakage got fixed" still be a failure? Let me walk through it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I did: rip frames from the video and train (v1)
&lt;/h2&gt;

&lt;p&gt;Simple steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract still frames from my hand-drawn animation video&lt;/li&gt;
&lt;li&gt;Roughly select ~300 of them as training material&lt;/li&gt;
&lt;li&gt;Train a LoRA on them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The training itself took &lt;strong&gt;17 minutes on the DGX&lt;/strong&gt;. Lightning fast.&lt;br&gt;
"Oh, this is easy," I thought — for about five minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Then I generated, and it was a mess
&lt;/h2&gt;

&lt;p&gt;Asking the finished LoRA for "single character" and "two-person scenes" gave me this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;How it broke&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fused heads&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A second body sprouts from the head / multiple faces merge into one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backgrounds won't go away&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Even asking for "white background," blue/pink backgrounds show up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Thick, muddy lines&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No clean line art, everything is heavy and blurry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ghost text&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Meaningless characters (leftover captions) get baked into the image&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It &lt;em&gt;could&lt;/em&gt; tell the characters apart (A and B were recognized as different people).&lt;br&gt;
But the looks were wrecked. Lined up, the actual outputs were quite the horror show:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0xevt3k0nq306nkaya8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0xevt3k0nq306nkaya8v.png" alt="Line art where bodies tangle together, you can't tell whose limbs are whose" width="512" height="768"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;▲ When two characters show up, you can't tell what's what anymore&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzeusi0o7hnn90flo62fu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzeusi0o7hnn90flo62fu.png" alt="A dinner-table scene where multiple faces fuse and multiply" width="512" height="768"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;▲ Faces fuse and multiply&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fau6i2xqwhmnebfzv8kpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fau6i2xqwhmnebfzv8kpc.png" alt="Line art covered in meaningless floating text" width="512" height="768"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;▲ Leftover captions bake in as "ghost text" all over the frame&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqh5kmmk9srjvbndn8w14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqh5kmmk9srjvbndn8w14.png" alt="A figure screaming as its body dissolves" width="512" height="768"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;▲ Train on high-motion frames and everything just melts&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why did it break? (the real point)
&lt;/h2&gt;

&lt;p&gt;The culprit was &lt;strong&gt;using video frames as the source itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A video, if you think about it, is footage with &lt;em&gt;many things happening at once&lt;/em&gt;. Rip a&lt;br&gt;
frame out of it and you don't just learn the character's shape — you learn all the&lt;br&gt;
surrounding noise too.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fused heads&lt;/td&gt;
&lt;td&gt;Video has lots of frames where &lt;strong&gt;two people move in the same shot&lt;/strong&gt;. The model learns an instant where bodies overlap as "one single body"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backgrounds stick&lt;/td&gt;
&lt;td&gt;Tons of background-laden frames get in. It learns "character = with this colored background" as a set, and you can't override it later&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thick lines&lt;/td&gt;
&lt;td&gt;Mid-motion frames are blurred; that blur bakes in as a "thick-line style"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ghost text&lt;/td&gt;
&lt;td&gt;Caption text sitting on the frames sneaks into the material and gets learned&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In one sentence: &lt;strong&gt;video is noise-laden material — motion, overlap, backgrounds, text&lt;br&gt;
all baked in&lt;/strong&gt; — and it's a poor way to cleanly extract just a character's shape.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuogk03gzxmsq9cvqgsuv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuogk03gzxmsq9cvqgsuv.png" alt="Line art with a pink background that won't go away, character multiplied" width="512" height="768"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;▲ Even asking for "white background," the training background color (pink) won't peel off — and the character multiplies for good measure&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Fixing it (v2)
&lt;/h2&gt;

&lt;p&gt;Now that I knew the causes, I &lt;strong&gt;rebuilt the data side&lt;/strong&gt; and trained again.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Auto-remove frames with caption text&lt;/li&gt;
&lt;li&gt;Drop "no character" frames — pure backgrounds, transition frames (~300 → 141 frames)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split into three groups&lt;/strong&gt; — "A only," "B only," "the two together" — to stop the
characters from bleeding into each other&lt;/li&gt;
&lt;li&gt;Switch the base model to an anime one (good at line art) and tune the settings&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;v1 (first)&lt;/th&gt;
&lt;th&gt;v2 (rebuilt)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fused heads&lt;/td&gt;
&lt;td&gt;✗ frequent&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✓ gone&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thick/muddy lines&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✓ thin and clean&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Line-art look&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✓✓ clearly line art&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backgrounds&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;△ white now, but color bleeds onto clothes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ghost text&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;△ far less, a little remains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resemblance to my characters (the whole point)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;✗ a different person — sometimes missing an arm&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Look at just the top of that table and you think "oh, it's fixed!" I did too, for a second.&lt;br&gt;
&lt;strong&gt;The noise problems (fused heads, thick lines, background color) really were fixed.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But look closer and there's &lt;strong&gt;no trace of my original characters.&lt;/strong&gt; The lines are clean,&lt;br&gt;
but what comes out is "some vaguely anime-style stranger." The worst ones are even missing&lt;br&gt;
an arm.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fubm0tzzjmq66jz8ch5el.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fubm0tzzjmq66jz8ch5el.png" alt="v2 line art of a single character cooking" width="512" height="768"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;▲ The lines are clean, sure — but it looks nothing like my original character. A stranger.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkx1amiumewvtl0qzfgbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkx1amiumewvtl0qzfgbh.png" alt="v2 line art of a single character standing" width="512" height="768"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;▲ Stable as a drawing. Still zero resemblance (and color still bleeds onto the clothes)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The real wall I never got past
&lt;/h2&gt;

&lt;p&gt;Even with the noise gone, &lt;strong&gt;the one thing I actually wanted — reproducing my own&lt;br&gt;
characters — was completely out of reach.&lt;/strong&gt; All I got was a clean-looking stranger.&lt;/p&gt;

&lt;p&gt;And since &lt;strong&gt;even a single character came out this much of a different person, "two of them&lt;br&gt;
together, in a scene with a relationship" was even more hopeless.&lt;/strong&gt; Ask for the two of them&lt;br&gt;
and only one shows up, or it falls apart.&lt;/p&gt;

&lt;p&gt;I chased down why two-person was &lt;em&gt;especially&lt;/em&gt; bad, too:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;There were only 9 real frames&lt;/strong&gt; in the entire set where the two were naturally side
by side&lt;/li&gt;
&lt;li&gt;I tried to get more by re-checking another 478 frames, but every "two-person" hit was
&lt;strong&gt;a false positive&lt;/strong&gt; (the detector reacting to on-screen text or body fragments)&lt;/li&gt;
&lt;li&gt;→ In other words, &lt;strong&gt;you cannot grow "two-person scenes" out of video material&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the composition you want (the two of them cleanly together) doesn't happen to exist in&lt;br&gt;
the video, you can't extract it after the fact. Obvious in hindsight — but it really sank&lt;br&gt;
in once I'd hit the wall.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's takeaway
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ripping frames from a video teaches the model "vaguely anime-ish" at best.&lt;br&gt;
It couldn't reproduce &lt;em&gt;my&lt;/em&gt; characters even for a single figure (let alone two / a&lt;br&gt;
relationship). In the end, you have to hand-draw the stills you want it to learn.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This isn't a sour-grapes conclusion — it's the answer after exhausting every way to grow&lt;br&gt;
the data. I took the long way around trying to be lazy, but because of it I now&lt;br&gt;
&lt;strong&gt;understand, first-hand, why hand-drawn stills are necessary.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Someday I'll act on this conclusion and &lt;strong&gt;prepare the compositions by hand&lt;/strong&gt; — but that's&lt;br&gt;
a project for another day.&lt;/p&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Training settings (v1 → v2)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;v1&lt;/th&gt;
&lt;th&gt;v2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Base model&lt;/td&gt;
&lt;td&gt;SD1.5 (plain)&lt;/td&gt;
&lt;td&gt;anime-style (good at line art)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;clip_skip&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;~300 lumped together&lt;/td&gt;
&lt;td&gt;split into 3 groups (68 / 64 / 9)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Epochs&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LoRA dim / alpha&lt;/td&gt;
&lt;td&gt;32 / 16&lt;/td&gt;
&lt;td&gt;32 / 16 (kept)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Training time (DGX)&lt;/td&gt;
&lt;td&gt;~17 min&lt;/td&gt;
&lt;td&gt;~14 min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In v2 I pinned a required character-name tag to the front of each group's captions&lt;br&gt;
(keep_tokens) to suppress the characters bleeding into each other.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why "two-person scenes" couldn't be grown
&lt;/h3&gt;

&lt;p&gt;I re-tagged another 478 video frames looking for "two people in frame." Co-occurrence&lt;br&gt;
flagged 25, but on full-resolution inspection almost all of them held only one person —&lt;br&gt;
the tagger was misfiring on on-screen text labels and body fragments. The real "two&lt;br&gt;
together" frames were the 9 I'd hand-picked at the start, basically the whole supply.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's still left (the homework)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Color bleeding onto clothes (likely from color tags in some groups)&lt;/li&gt;
&lt;li&gt;Leftover ghost text (a little text-like noise remains)&lt;/li&gt;
&lt;li&gt;And the big one: &lt;strong&gt;reproducing the characters at all. Neither single figures nor pairs
actually look like "my" characters → hand-draw the compositions I need&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Next up
&lt;/h2&gt;

&lt;p&gt;Next time I'm switching things up with a completely different experiment 🎬&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>stablediffusion</category>
    </item>
    <item>
      <title>[Day 11] I turned my cat into anime art — and the AI drew a human girl instead. One photo through IPAdapter pulls it back to a cat</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Thu, 04 Jun 2026 04:13:23 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-11-i-turned-my-cat-into-anime-art-and-the-ai-drew-a-human-girl-instead-one-photo-through-4dkp</link>
      <guid>https://dev.to/peppercorn_llm/day-11-i-turned-my-cat-into-anime-art-and-the-ai-drew-a-human-girl-instead-one-photo-through-4dkp</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 11! Back to cats 🐱&lt;/p&gt;

&lt;p&gt;I took one photo of my cat (a black-and-white tuxedo boy) as a reference and had AI restyle him into anime, ukiyo-e, oil painting, and more.&lt;/p&gt;

&lt;p&gt;The goal: change only the style while keeping "my cat" recognizable. But left alone, the AI started drawing humans instead of a cat. Here's what I did, step by step.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: my home AI machine (DGX Spark) + an image-generation tool (ComfyUI) + one photo of my cat.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The reference is this one photo
&lt;/h2&gt;

&lt;p&gt;A tomcat my family looks after for me, with yellow eyes and a slightly grumpy look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8jxkykpjz4zow2i2hh0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8jxkykpjz4zow2i2hh0.png" alt="The reference photo of my cat" width="768" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Love that face. I'll turn him into various styles while keeping him recognizable as "my cat."&lt;/p&gt;




&lt;h2&gt;
  
  
  First, anime from text alone → a human
&lt;/h2&gt;

&lt;p&gt;I started with no photo, just text: "a tuxedo cat, anime key visual." I clearly said &lt;em&gt;cat&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52m7gp8s46ajvka5ha2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52m7gp8s46ajvka5ha2x.png" alt="Anime from text alone, no reference photo" width="768" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what came out. …A human girl.&lt;/p&gt;

&lt;p&gt;Black hair, white collar. My cat's tuxedo pattern (black body, white chest) turned straight into clothing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next, I added the reference photo → still human
&lt;/h2&gt;

&lt;p&gt;So I hand over the cat photo as a &lt;em&gt;visual reference&lt;/em&gt;. The tool that applies it is IPAdapter.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What's the reference-photo trick (IPAdapter)?&lt;/strong&gt; A tool that lets you pass a reference &lt;em&gt;image&lt;/em&gt;, separate from the text prompt, and say "make it look like this." It's what preserves my cat's colors and face.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Surely &lt;em&gt;this&lt;/em&gt; makes it a cat… nope. Still human.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Far610w7ixrcand0etspy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Far610w7ixrcand0etspy.png" alt="Even with the reference photo added, still a human" width="768" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this habit wasn't limited to anime. Ask the same anime-style model for ukiyo-e or oil painting, and you still get anime-ish humans. It hijacks not just the subject (the cat), but the art style too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ccueo6n78a1bm7x221m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ccueo6n78a1bm7x221m.png" alt="Ask for ukiyo-e or oil painting, you still get anime-style humans" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Left: an "ukiyo-e" that's really an anime woman in a kimono. Right: an "oil painting" that's an anime woman in a tuxedo. Both are "humans painted in the cat's colors."&lt;/p&gt;




&lt;h2&gt;
  
  
  I tuned the settings → finally a cat
&lt;/h2&gt;

&lt;p&gt;On top of the photo, I turned up its strength and added "don't draw humans" to the negatives (details below). That's when it finally became a sitting cat.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsge68cvgiaxp3hcaf9z9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsge68cvgiaxp3hcaf9z9.png" alt="Photo plus tuned settings finally gives a cat" width="768" height="768"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why does it turn into a human?
&lt;/h2&gt;

&lt;p&gt;Two reasons, as far as I can tell.&lt;/p&gt;

&lt;p&gt;One: anime-savvy models tend to draw people, girls especially. Even with "cat" in the prompt, they drift toward a human if you let them.&lt;/p&gt;

&lt;p&gt;Two: my cat's pose. He sits bolt upright, almost like a person, so the harder you push the reference, the more that upright posture rides along — tipping toward an "anthropomorphized" cat. The pop-art piece later is exactly that leftover.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cyberpunk flipped to a cat with the photo alone
&lt;/h2&gt;

&lt;p&gt;The interesting part: whether the photo alone was enough depended on the model. Anime was stubborn and needed tuning, but cyberpunk became a cat just by adding the photo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4or2x14ierhix5j9bc6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4or2x14ierhix5j9bc6c.png" alt="Cyberpunk: same prompt, with vs. without the reference photo" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Left (no reference): a human man in a neon city. Right (with reference): a cat with glowing ears.&lt;/p&gt;

&lt;p&gt;I didn't change a single character of the prompt — the photo being there or not is the only difference between human and cat.&lt;/p&gt;




&lt;h2&gt;
  
  
  The styles that came out
&lt;/h2&gt;

&lt;p&gt;Here's the gallery after the human problem was fixed — all with the reference photo, my cat as the base.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9glp3evvd2l40s34qbxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9glp3evvd2l40s34qbxy.png" alt="Gallery of 7 styles" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Top row, left to right: anime, ukiyo-e, oil painting (Van Gogh-ish), stained glass. Bottom row: cyberpunk, 3D (Pixar-ish), pop art.&lt;/p&gt;




&lt;h2&gt;
  
  
  "Likeness" and "style" are a tug-of-war
&lt;/h2&gt;

&lt;p&gt;The oddly real 3D Pixar one shows this little trade-off nicely.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F043tslc6hn8dqxw4awbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F043tslc6hn8dqxw4awbc.png" alt="3D style: without (left) and with (right) the reference" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Left (no reference): a cute 3D cat, but "some cat." Right (with reference): it becomes my cat's face, but the 3D look washes out into basically a real photo.&lt;/p&gt;

&lt;p&gt;Weaken the reference and the style shows but it's a different cat; strengthen it and it's my cat but the style fades. Finding that grip per style is what the tuning really is.&lt;/p&gt;




&lt;h2&gt;
  
  
  The boss I couldn't beat: storybook watercolor
&lt;/h2&gt;

&lt;p&gt;"Gentle storybook watercolor" was the one style I never got to be a cat. Here's the result of seven retries.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhtbx4k3etvbyoxdl385o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhtbx4k3etvbyoxdl385o.png" alt="Storybook failures: a person, two cats, a cat-girl" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A human, then somehow two cats, then a cat-eared girl holding a cat. "Single + watercolor + cat" wouldn't line up. Lower the reference → human; raise it → two cats. "Storybook" must be soaked in human imagery. Carrying this over.&lt;/p&gt;




&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;p&gt;Here are the details.&lt;/p&gt;

&lt;h3&gt;
  
  
  The reference-photo mechanism (IPAdapter)
&lt;/h3&gt;

&lt;p&gt;I added a custom node called &lt;code&gt;ComfyUI_IPAdapter_plus&lt;/code&gt; to ComfyUI. It lets you hand over a reference image as a "visual guide," separate from the text prompt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model used: &lt;code&gt;ip-adapter_sd15&lt;/code&gt; (44.6MB, from h94/IP-Adapter)&lt;/li&gt;
&lt;li&gt;The part that reads the image features: &lt;code&gt;CLIP-ViT-H&lt;/code&gt; (reused an existing one)&lt;/li&gt;
&lt;li&gt;The reference photo is cropped to a 768px square before handing it over&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A number called the "reference strength (weight)" controls how closely it mimics. I moved between roughly 0.7 and 0.85 depending on the style.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I did to suppress the "human" problem
&lt;/h3&gt;

&lt;p&gt;I started at weight 0.7 plus words like "key visual" and "big eyes," which strongly invited humans. Three fixes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Raise the reference strength to 0.85&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;human, girl, person, 1girl, humanoid&lt;/code&gt; to the "things I don't want drawn" list&lt;/li&gt;
&lt;li&gt;Strip human-summoning words from the request and emphasize &lt;code&gt;tuxedo cat, full body, animal&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That corrected anime, ukiyo-e, and oil painting into cats. One catch: the phrase "tuxedo cat" itself tends to put an actual tuxedo (a suit) on the cat, so it cut both ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  The base models I used
&lt;/h3&gt;

&lt;p&gt;I switched the underlying image model by style.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anime / illustration: &lt;code&gt;AnythingV5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Realistic / 3D: &lt;code&gt;Realistic Vision V6&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Plain base: &lt;code&gt;SD 1.5&lt;/code&gt; (base)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When storybook failed, switching to the plain base gave a real cat but weak watercolor feel, and raising the strength split it into two cats — a real bind. The base model's "habits" matter a lot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common generation settings
&lt;/h3&gt;

&lt;p&gt;Across all styles: 768px, 30 steps, sampler &lt;code&gt;dpmpp_2m karras&lt;/code&gt;, cfg 7, seed fixed at 110011. I only varied the text request and the reference strength, keeping everything else equal for a fair comparison. Generation is fired at ComfyUI from a small script I wrote.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next up
&lt;/h2&gt;

&lt;p&gt;Next time it's cats again — and this time I'm planning video generation 🐱&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>stablediffusion</category>
    </item>
    <item>
      <title>[Day 10] Building my own personal weather officer AI, and teaching it my body's sense of cold over the next 100 days</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Mon, 01 Jun 2026 01:31:58 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-10-building-my-own-personal-weather-officer-ai-and-teaching-it-my-bodys-sense-of-cold-over-26d3</link>
      <guid>https://dev.to/peppercorn_llm/day-10-building-my-own-personal-weather-officer-ai-and-teaching-it-my-bodys-sense-of-cold-over-26d3</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 10!&lt;/p&gt;

&lt;p&gt;This time I'm starting a longer-running experiment. Meet the "weather officer AI" — a bot that texts me every morning saying "wear this today." The plan is to build a weather assistant that's tuned to &lt;em&gt;me&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What I'm building today is just v0.1 (the very first version). From here through Day 100, I'll keep teaching it "too cold / just right / too warm" every morning, so it gradually learns my preferences. The experiment is: how smart does it get after 100 days?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: my home AI machine (DGX Spark) + free weather data + a phone messaging app (Telegram)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Today's task
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I wanted
&lt;/h3&gt;

&lt;p&gt;I live somewhere with a big daily temperature swing, and "what do I wear today?" is a small but real daily headache. Weather apps tell you the temperature, but whether &lt;em&gt;I&lt;/em&gt; feel cold is a different question.&lt;/p&gt;

&lt;p&gt;So the starting point was: can I build a clothing AI that's tuned to "how I feel," not just "the temperature"?&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach
&lt;/h3&gt;

&lt;p&gt;I kept the design dead simple.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every morning at 7, automatically fetch today's weather&lt;/li&gt;
&lt;li&gt;Decide "this morning's outfit" from the apparent temperature and push it to my phone&lt;/li&gt;
&lt;li&gt;I just tap back "cold / just right / warm"&lt;/li&gt;
&lt;li&gt;As these feelings pile up, the AI learns "this person runs cold" and corrects its suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The goal this time
&lt;/h3&gt;

&lt;p&gt;Not a "perfect forecast AI," but a "routine I can actually keep up every day." The smarts get grown over the next 100 days. Today is just laying the rails.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 How much does the temperature actually move in a day?
&lt;/h2&gt;

&lt;p&gt;Before building anything, I pulled a week of apparent temperatures for where I live and graphed it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgciz2ogzi4dvc7meb2cl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgciz2ogzi4dvc7meb2cl.png" alt="Apparent temperature through the day"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A beautiful zigzag. Every day repeats "cold in the morning → way up by midday → down again at night." The average daily swing is 13°C, and on the biggest day it moved 20°C.&lt;/p&gt;

&lt;p&gt;So I narrowed the suggestion down to "one outfit, at 7 a.m., matched to the apparent temperature at that hour." I record just once in the morning too. To keep something up for 100 days, simplicity matters most.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The AI doesn't learn the temperature swing itself. But by deciding to "focus on the morning," the suggestion and the feedback line up in time, so later I can cleanly check "was the morning suggestion right?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔧 How it works (the morning loop)
&lt;/h2&gt;

&lt;p&gt;The finished weather officer runs on this loop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9b01emkwxk15l19ksyh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9b01emkwxk15l19ksyh6.png" alt="The weather officer's morning loop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At 7 a.m. it grabs the weather, decides the outfit, and pushes a notification. I tap back my feeling, and that gets recorded. Once those records pile up, step 5 — learning "you run cold / warm" — kicks in, and the suggestions gradually become mine.&lt;/p&gt;

&lt;p&gt;Here's what the actual notification looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;☀️ Weather Officer AI — good morning

👕 This morning's outfit: long sleeves

This morning feels like: 13°C (highs up to 20°C today)
Rain: 4%  /  Wind: 13 km/h

How does it feel this morning? ↓ tap to tell me
   [🥶 cold]  [😊 just right]  [🥵 warm]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It suggests one outfit, but adds "highs up to 20°C today" so I can decide whether to throw on a layer myself. Tapping a button changes it to "✅ recorded," and the feeling is saved to my home AI.&lt;/p&gt;

&lt;p&gt;The notifications go through the messaging app I already use (Telegram).&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ The details
&lt;/h2&gt;

&lt;p&gt;Below are the specifics.&lt;/p&gt;

&lt;p&gt;The weather data&lt;/p&gt;

&lt;p&gt;Weather comes from &lt;a href="https://open-meteo.com/" rel="noopener noreferrer"&gt;Open-Meteo&lt;/a&gt;, a free weather API. No API key needed, historical data available, and commercial use is OK (CC BY 4.0) — very generous.&lt;/p&gt;

&lt;p&gt;I mostly use "apparent temperature" — not the raw air temperature, but a number adjusted for wind and humidity to reflect how it actually feels, which is better for deciding what to wear. I take the average apparent temperature from 7–9 a.m. as "this morning's feel." The coordinates stay only on my home machine; I don't write the specific location in the article or the code.&lt;/p&gt;

&lt;p&gt;The clothing rule&lt;/p&gt;

&lt;p&gt;A plain rule that splits apparent temperature into 7 bands, each mapped to an outfit (e.g. 13–20°C → long sleeves, 20–26°C → short sleeves).&lt;/p&gt;

&lt;p&gt;There's one "personal offset" number baked in. It's zero for now (v0.1). Going forward, if "cold" keeps coming back, I'll push the offset negative so the same temperature suggests warmer clothes — growing it from the feedback.&lt;/p&gt;

&lt;p&gt;The notification and buttons&lt;/p&gt;

&lt;p&gt;The notification uses a Telegram "Bot" (a thing that sends messages automatically), built with the &lt;code&gt;python-telegram-bot&lt;/code&gt; library to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;send a message at a fixed time every morning at 7&lt;/li&gt;
&lt;li&gt;attach three buttons below it and record which one is pressed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This bot sits waiting inside my home AI machine and fires in the morning.&lt;/p&gt;

&lt;p&gt;The shape of the feeling log (the 100-day foundation)&lt;/p&gt;

&lt;p&gt;Each record is one line per day, with these fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;date&lt;/li&gt;
&lt;li&gt;that day's forecast (morning/daytime apparent temperature, wind, rain chance)&lt;/li&gt;
&lt;li&gt;the outfit the AI suggested&lt;/li&gt;
&lt;li&gt;my feeling (cold / just right / warm)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kept in this consistent shape, I can later graph "monthly hit rate" or "my personal bias." I'll report this trend in the Day 21 / 36 / 54 / 74 / 87 check-ins.&lt;/p&gt;

&lt;p&gt;Keeping it running&lt;/p&gt;

&lt;p&gt;So the 7 a.m. notification reliably fires, I set the bot to launch automatically when the machine boots (systemd). Even after a reboot it comes back on its own, and the morning notification keeps going.&lt;/p&gt;

&lt;p&gt;The feeling log and the notification settings (the Telegram token, etc.) are all stored only on my home machine — none of it goes anywhere external like GitHub.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 100-day growth plan
&lt;/h2&gt;

&lt;p&gt;I'll keep growing this weather officer across the series — it'll pop up here and there.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Milestone&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Day 10 (now)&lt;/td&gt;
&lt;td&gt;v0.1 done; the recording loop starts turning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 21&lt;/td&gt;
&lt;td&gt;First "my personal bias" report from 11 days of data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 36&lt;/td&gt;
&lt;td&gt;Graph the monthly hit rate and take a look&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 54 / 74 / 87&lt;/td&gt;
&lt;td&gt;Mid-reviews: seasonal changes in feel, how the correction works&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Day 100&lt;/td&gt;
&lt;td&gt;The 100-day accuracy trend and the finished version&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Just tap a button every morning. I'm curious how "mine" it'll feel after 100 days.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next time: Day 11
&lt;/h2&gt;

&lt;p&gt;Next time it's a hard pivot back to cats 🐱 I'll convert photos of my cat into picture-book, anime, and photorealistic styles — the theme being whether I can keep "that's-our-cat-ness" while changing only the style.&lt;/p&gt;

&lt;h1&gt;
  
  
  LocalLLM #100ExperimentsWithDGX
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>python</category>
    </item>
    <item>
      <title>[Day 9] A local Japanese sentiment AI (BERT) read 8 years of a LINE chat, and the ups and downs surfaced from numbers alone</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Fri, 29 May 2026 22:39:10 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-9-a-local-japanese-sentiment-ai-bert-read-8-years-of-a-line-chat-and-the-ups-and-downs-4951</link>
      <guid>https://dev.to/peppercorn_llm/day-9-a-local-japanese-sentiment-ai-bert-read-8-years-of-a-line-chat-and-the-ups-and-downs-4951</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 9. Today is less about model internals and more of a personal experiment: have a local AI analyze the entire chat history with one LINE friend. (LINE is the dominant messaging app in Japan.)&lt;/p&gt;

&lt;p&gt;When I exported it, 8 years were sitting there — from the very first message to today. It started, we talked a lot, it went quiet for a while, then picked up again. That whole arc is in there.&lt;/p&gt;

&lt;p&gt;Because the content is what it is, nothing left my machine: everything ran locally on my DGX Spark.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What I used: my home AI box (DGX Spark) + a Japanese sentiment model (for tone) + a bigger local model (to guess events from numbers).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Today's setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I wanted to do
&lt;/h3&gt;

&lt;p&gt;Re-reading 8 years of messages one by one isn't realistic. So instead of reading the content, I looked only at the "shape" of the conversation — when, how much, and in what tone we talked.&lt;/p&gt;

&lt;p&gt;Concretely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;monthly message volume&lt;/li&gt;
&lt;li&gt;the trend of tone (positive / negative)&lt;/li&gt;
&lt;li&gt;then asking an AI to find "when something big happened"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Heads-up (the result)
&lt;/h3&gt;

&lt;p&gt;From message counts and tone alone, the 8-year arc came out clearly on a chart. Started, went quiet, came back — the flow was visible without me re-reading a thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔧 Pipeline
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LINE chat export (text)
        │
        ▼
 1. Parse: split each message into {datetime, who, type, text}
        │   (from here on, message text never leaves the machine)
        ▼
 2. Aggregate: monthly counts, time-of-day, reply gaps
        │
        ▼
 3. Tone scoring: classify each of 66k messages pos/neu/neg
        │
        ▼
 4. Turning-point detection: from sudden changes in the numbers
        │   + also show ONLY the numbers to a bigger AI and ask it to guess
        ▼
 5. Answer check: compare against the real timeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can export a LINE chat as text from the chat screen ("send chat history").&lt;/p&gt;

&lt;p&gt;Data size:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Span&lt;/td&gt;
&lt;td&gt;~8 years 2 months&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total messages&lt;/td&gt;
&lt;td&gt;87,621&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Text messages&lt;/td&gt;
&lt;td&gt;66,329&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stickers&lt;/td&gt;
&lt;td&gt;15,605&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Photos&lt;/td&gt;
&lt;td&gt;3,982&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;15,605 stickers… that's a lot.&lt;/p&gt;

&lt;h3&gt;
  
  
  The two AIs
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;What it sees&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3. Tone&lt;/td&gt;
&lt;td&gt;Japanese sentiment model (&lt;code&gt;koheiduck/bert-japanese-finetuned-sentiment&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;scores each message pos/neu/neg&lt;/td&gt;
&lt;td&gt;66k message texts (scores averaged per month)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Turning points&lt;/td&gt;
&lt;td&gt;a bigger local model (&lt;code&gt;Qwen2.5&lt;/code&gt; 72B)&lt;/td&gt;
&lt;td&gt;guesses "what happened to these two?"&lt;/td&gt;
&lt;td&gt;only the per-month table of counts + tone scores (no conversation, no words)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both run locally on my own machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The 8-year arc of volume and tone
&lt;/h3&gt;

&lt;p&gt;This chart is the highlight. Top: monthly message count. Bottom: tone (up = positive, down = negative). The x-axis is months since the conversation started. (Axis labels are in Japanese.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvlmf9tb0ah7rwakmqo3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvlmf9tb0ah7rwakmqo3.png" alt="8-year message volume and tone"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plotted, it isn't a steady climb or a flat line — it splits cleanly into "chapters": ramp-up → an 8-month silence → a second peak → a stable plateau. Four phases, at a glance.&lt;/p&gt;

&lt;p&gt;Tone has two peaks of about +0.6, around the start and around when things resumed (overall mean ≈ 0, slightly negative in the later years). The interesting part: in the month &lt;em&gt;before&lt;/em&gt; the silence, tone had already dropped to −0.1. The mood dimmed before the volume did.&lt;/p&gt;

&lt;p&gt;There are two dips into negative tone. The one before the silence was an "omen." The other is the recent years — not an omen, but the effect of logistics-y messages ("what time are you home?") piling up.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Mini-note: how is "tone" turned into a number?&lt;br&gt;
The scoring is done by a Japanese sentiment model. Roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pre-trained on lots of Japanese text labeled positive / negative&lt;/li&gt;
&lt;li&gt;judges with context, not just by spotting keywords&lt;/li&gt;
&lt;li&gt;returns a probability of "positive-ness" / "negative-ness" per message&lt;/li&gt;
&lt;li&gt;I used the difference as a per-message score&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What kinds of messages scored how?
&lt;/h3&gt;

&lt;p&gt;A few actual judgments (short, name- and place-free one-liners):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Message&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;「楽しかったね！」 (that was fun!)&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;「これめちゃうまい」 (this is so good)&lt;/td&gt;
&lt;td&gt;Positive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;「おはようございます」 (good morning)&lt;/td&gt;
&lt;td&gt;Neutral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;「もうお家？」 (home already?)&lt;/td&gt;
&lt;td&gt;Neutral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;「全く集中できない」 (can't focus at all)&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;「それは悔しいな、、」 (that's frustrating…)&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(a long trip-planning message)&lt;/td&gt;
&lt;td&gt;Neutral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(a snappy one-liner sent in a huff)&lt;/td&gt;
&lt;td&gt;Negative&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Plain happy lines score positive; logistics ("good morning", "home already?") score neutral; tiredness or irritation scores negative. Even long, businesslike planning messages lean neutral.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mornings are when we talk
&lt;/h3&gt;

&lt;p&gt;Message density by weekday × hour (brighter = more).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdnp6m5ynqfxirqyvw9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdnp6m5ynqfxirqyvw9i.png" alt="weekday × hour density"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A clear concentration at 7–9 a.m.!&lt;/p&gt;

&lt;h3&gt;
  
  
  Could the AI guess the turning points?
&lt;/h3&gt;

&lt;p&gt;First, the simple method: mechanically pick the points where message volume jumped or dropped, then check against the real timeline.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Real event&lt;/th&gt;
&lt;th&gt;Auto-detected timing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;When it started&lt;/td&gt;
&lt;td&gt;exact match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;When it went quiet&lt;/td&gt;
&lt;td&gt;exact match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;When it resumed&lt;/td&gt;
&lt;td&gt;exact match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;When it got lively again&lt;/td&gt;
&lt;td&gt;a few months off&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A big life milestone&lt;/td&gt;
&lt;td&gt;hard to detect (barely shows in counts)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sharp volume changes were nailed. But "a big life milestone" got missed. So I showed the &lt;em&gt;same numbers&lt;/em&gt; to the bigger local model and asked "what happened?" — and got back:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"around when it started" → roughly matches&lt;/li&gt;
&lt;li&gt;"a stretch of going silent" → matches the quiet period&lt;/li&gt;
&lt;li&gt;"a major life change" → almost exactly before the real milestone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than hunting for a single spike, it reads the whole sequence of numbers as a "flow," so it could pick up even an event that barely moves the counts.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Takeaways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Volume + tone alone reveal the arc
&lt;/h3&gt;

&lt;p&gt;Counts and tone were enough to see the 8-year shape. Silence marks the quiet stretch; a surge marks the resumption — straight off the chart.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A local model reads a story out of numbers
&lt;/h3&gt;

&lt;p&gt;Given only monthly numbers, the model inferred even a barely-visible event ("something big around here"), and it lined up with reality. It connects scattered points into one flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A "negative" tone doesn't mean a bad relationship
&lt;/h3&gt;

&lt;p&gt;The slight negative lean in later years isn't about getting along badly. Logistics messages ("what time are you home?") just don't score high. Low score ≠ trouble. It isn't that sentiment analysis is poor — the scores need to be read together with context.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Technical details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Parsing &amp;amp; aggregation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;LINE export format is a date header plus &lt;code&gt;time&amp;lt;TAB&amp;gt;name&amp;lt;TAB&amp;gt;text&lt;/code&gt;. Multi-line messages (4,987 of them) are merged back into the previous message.&lt;/li&gt;
&lt;li&gt;Speakers normalized to "A / B" by message count (no real names in anything public). Temporary group members and system lines excluded.&lt;/li&gt;
&lt;li&gt;Messages tagged by type (text / sticker / photo / call / unsent…). Tone uses text only; volume counts use all types.&lt;/li&gt;
&lt;li&gt;Aggregation and plotting in Python (pandas / matplotlib).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tone (sentiment)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;koheiduck/bert-japanese-finetuned-sentiment&lt;/code&gt;, a 3-class (pos / neu / neg) Japanese model.&lt;/li&gt;
&lt;li&gt;66,329 texts scored on GPU in batches; per message I take P(pos) − P(neg) in [−1, +1], then average per month.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Turning-point detection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Rule-based: long near-zero stretches (silence), large month-over-month surges, and tone peaks — all from numbers only.&lt;/li&gt;
&lt;li&gt;Plus: the per-month table of counts + tone scores fed to a bigger local model (Qwen2.5-72B via ollama) to guess events. No message text was given.&lt;/li&gt;
&lt;li&gt;Real event dates were kept in a local note only, used for annotation and the answer check.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Every file containing message text (raw export, parsed data, scores) stays in a non-public folder.&lt;/li&gt;
&lt;li&gt;Only aggregate numbers and charts are published. The chart x-axis is relativized to "months since the conversation started," hiding actual dates.&lt;/li&gt;
&lt;li&gt;Apart from a few short, name- and place-free one-liners shown as scoring examples, no conversation content, real names, specific dates, or long text appears in the article or charts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tomorrow: Day 10
&lt;/h2&gt;

&lt;p&gt;Weather forecasts say one temperature, but everyone &lt;em&gt;feels&lt;/em&gt; it differently. Same degrees, different "do I need a coat?" So next I'm building my own personal "weather officer" AI: from past weather data, it'll tell me each morning something like "coat + beanie today." Over the next 100 days I'll teach it my own sense of cold — the start of a longer project.&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>privacy</category>
    </item>
    <item>
      <title>[Day 8] Pushing Looped Transformers Beyond Addition: OpenMythos on Bracket-Matching Depth</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Fri, 29 May 2026 06:27:04 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-8-pushing-looped-transformers-beyond-addition-openmythos-on-bracket-matching-depth-4bgd</link>
      <guid>https://dev.to/peppercorn_llm/day-8-pushing-looped-transformers-beyond-addition-openmythos-on-bracket-matching-depth-4bgd</guid>
      <description>&lt;h1&gt;
  
  
  [Day 8] Pushing Looped Transformers Beyond Addition: OpenMythos on Bracket-Matching Depth
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 8!&lt;/p&gt;

&lt;p&gt;A direct follow-up to &lt;a href="https://dev.to/peppercorn_llm/day-7-openmythos-loop-debate"&gt;Day 7&lt;/a&gt;: same OpenMythos-style mini model (3.4M params), same training pipeline, &lt;strong&gt;one task change&lt;/strong&gt; — multi-digit addition swapped for nested-bracket parsing. The goal was to ask two follow-up questions Day 7 left open:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Does the "training-time loop count is the peak" finding generalize across tasks?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If we increase the structural complexity of the input (deeper nesting), does inference-time loop count start to matter?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Tools used: my home AI machine (DGX Spark, GB10) + &lt;a href="https://github.com/kyegomez/OpenMythos" rel="noopener noreferrer"&gt;OpenMythos&lt;/a&gt; (PyTorch reconstruction of the rumored Claude Mythos architecture) + synthetic bracket sequences.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Today's setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why bracket matching?
&lt;/h3&gt;

&lt;p&gt;Day 7's task was 2-5 digit addition. Addition tests "carry propagation from low to high digit" — a fundamentally local, left-to-right state update. To probe whether looped depth helps with a different kind of structural reasoning, I wanted a task where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The output depends on &lt;em&gt;left-to-right state tracking&lt;/em&gt; (rules out attention-based global aggregation shortcuts).&lt;/li&gt;
&lt;li&gt;The task admits an explicit notion of &lt;em&gt;depth&lt;/em&gt; I can vary as a controlled difficulty knob.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bracket matching fits both. The standard linear-time algorithm is push-on-open / pop-on-close with a stack. A model that has internalized that algorithm should scale gracefully with depth — and one that hasn't will visibly fall over.&lt;/p&gt;

&lt;h3&gt;
  
  
  Task: first-break-position prediction
&lt;/h3&gt;

&lt;p&gt;Input: a string of &lt;code&gt;( ) [ ] { }&lt;/code&gt; characters, terminated by &lt;code&gt;=&lt;/code&gt;.&lt;br&gt;
Output: the &lt;strong&gt;left-most position at which the bracket structure breaks&lt;/strong&gt;, as 2 digits, terminated by &lt;code&gt;$&lt;/code&gt;. If the sequence is balanced, output &lt;code&gt;--$&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;((()))=          → --$       (balanced)
([{}])=          → --$       (balanced)
([)]=            → 02$       ()` at position 2 doesn't match preceding `[`)
(()(=            → 04$       (stack non-empty at end of string, position = len)
))=              → 00$       (close on empty stack at position 0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "break position" is defined by a stack parser scanning left-to-right:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Close bracket whose type ≠ stack top → return that close position.&lt;/li&gt;
&lt;li&gt;Close bracket on empty stack → return that close position.&lt;/li&gt;
&lt;li&gt;End of string with non-empty stack → return &lt;code&gt;len(s)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Otherwise balanced → return &lt;code&gt;-1&lt;/code&gt; (output &lt;code&gt;--&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why not just binary balanced / imbalanced?
&lt;/h3&gt;

&lt;p&gt;That was the original plan. A first smoke run with &lt;code&gt;T&lt;/code&gt;/&lt;code&gt;F&lt;/code&gt; output saturated to 100% accuracy across all depths (up to 10) by step 4,000. There are too many shortcut signals — length parity, open/close count, etc. — for a transformer to learn the actual stack algorithm.&lt;/p&gt;

&lt;p&gt;The first-break-position output forces the model to commit to a specific character position, which can only be answered by tracking state left-to-right. After this change, smoke results at 5,000 steps showed clean depth-dependent difficulty (d=2: 100%, d=20: 71%) and the loss had room to keep dropping. That's the signal I needed to study loop-count behavior meaningfully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Difficulty knob: depth
&lt;/h3&gt;

&lt;p&gt;I trained and evaluated across depths &lt;code&gt;{2, 4, 6, 8, 10, 12, 16, 20}&lt;/code&gt;, with pair count capped at &lt;code&gt;min(2 * depth, 50)&lt;/code&gt; so the 2-digit position output stays in range. Balanced and imbalanced sequences mixed 50/50; imbalanced sequences generated by deleting a close (30%), deleting an open (30%), or substituting a bracket (40%).&lt;/p&gt;

&lt;h3&gt;
  
  
  Architectural changes from Day 7
&lt;/h3&gt;

&lt;p&gt;Minimal — only what the new vocab and longer sequences required:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Day 7 (addition)&lt;/th&gt;
&lt;th&gt;Day 8 (brackets)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vocab_size&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_seq_len&lt;/td&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;max_loop_iters (train)&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Difficulty axis&lt;/td&gt;
&lt;td&gt;2-5 digits&lt;/td&gt;
&lt;td&gt;depth 2-20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Answer tokens&lt;/td&gt;
&lt;td&gt;1-6 (digits + &lt;code&gt;$&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;2 + &lt;code&gt;$&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total params&lt;/td&gt;
&lt;td&gt;3.39M&lt;/td&gt;
&lt;td&gt;3.39M&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same &lt;code&gt;MythosConfig&lt;/code&gt; template otherwise. Same hyperparameters (AdamW, max LR 3e-4, warmup 2000, cosine decay, 30k steps, fp32, 4 seeds in parallel).&lt;/p&gt;

&lt;h3&gt;
  
  
  Headline finding
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Day 7 "peak at training loop count" finding generalizes.&lt;/strong&gt; With training &lt;code&gt;max_loop_iters=4&lt;/code&gt;, accuracy peaks at exactly T=4 again, and decays in both directions — including at every depth I tested.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;But the peak height is much lower.&lt;/strong&gt; Best accuracy was 66% at depth 2; depth 20 caps at ~36%. Day 7 hit 100% at d=5; brackets at the same parameter budget plateau dozens of points short.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference-time loop extrapolation does NOT improve deep-nesting performance.&lt;/strong&gt; The hypothesis "deeper inputs benefit from more loops" did not reproduce — T&amp;gt;4 hurts at every depth, just as in Day 7.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixed-point reproduced, slightly later.&lt;/strong&gt; Cosine similarity between consecutive hidden states reaches ~0.95 by T=3 and ~0.99 by T=4 — a step or two later than addition (which got there by T=2).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🪢 The task in pictures
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input:  ( ( [ ) ] ) =
Pos:    0 1 2 3 4 5

stack walk:
  pos 0: '(' → push '('             stack: ( 
  pos 1: '(' → push '('             stack: ( (
  pos 2: '[' → push '['             stack: ( ( [
  pos 3: ')' → top is '[', mismatch!  → first break at position 3

Expected output: 03$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting thing about this task vs. addition: the answer can be &lt;strong&gt;anywhere from 0 to ~40&lt;/strong&gt; depending on the input, and the model has to &lt;em&gt;commit to a specific integer&lt;/em&gt;. There's no global-aggregation shortcut — you have to walk left-to-right and remember what you've seen.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 Pipeline
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenMythos tiny (3.4M params, same as Day 7 modulo vocab + max_seq_len)
  ↓
Train 4 seeds in parallel, 30k steps, fp32 on DGX Spark (GB10)
  ↓
Experiment A: greedy autoregressive accuracy
              loops ∈ {1, 2, 4, 8, 16, 32}  ×  depth ∈ {2, 4, 6, 8, 10, 12, 16, 20}
  ↓
Experiment B: cosine similarity between consecutive hidden states
              ⇒ does the recurrent block reach a fixed-point?
              ⇒ does the fixed-point timing depend on depth?
  ↓
Compare against Day 7 (digits) along the same axes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Training throughput note (vs Day 7)
&lt;/h3&gt;

&lt;p&gt;Day 7's 4-seed parallel training was fast because &lt;code&gt;max_seq_len=32&lt;/code&gt; left the GPU underutilized per process. With &lt;code&gt;max_seq_len=128&lt;/code&gt;, a single process already saturates the GB10 — 4-seed parallel drops per-process throughput from ~60K tok/s to ~12.8K tok/s (a -79% per-process penalty). Aggregate parallel throughput is actually ~15% &lt;em&gt;slower&lt;/em&gt; than sequential 4-seed.&lt;/p&gt;

&lt;p&gt;I let it run in parallel anyway because it was overnight and I had no other DGX usage scheduled. Worth noting for anyone planning similar replications: longer sequences kill the "free" benefit of multi-seed parallelism on a single GPU.&lt;/p&gt;

&lt;p&gt;GPU draw stayed at 51W / 72°C / 95% utilization throughout — comfortable enough to leave running.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Experiment A: accuracy heatmap
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F356tfullz8sf5zb06gc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F356tfullz8sf5zb06gc5.png" alt="accuracy heatmap of bracket-matching across loop counts and depths"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mean exact-match accuracy across 4 seeds, 500 eval samples per condition:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Inference loops&lt;/th&gt;
&lt;th&gt;d=2&lt;/th&gt;
&lt;th&gt;d=4&lt;/th&gt;
&lt;th&gt;d=6&lt;/th&gt;
&lt;th&gt;d=8&lt;/th&gt;
&lt;th&gt;d=10&lt;/th&gt;
&lt;th&gt;d=12&lt;/th&gt;
&lt;th&gt;d=16&lt;/th&gt;
&lt;th&gt;d=20&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.11&lt;/td&gt;
&lt;td&gt;0.05&lt;/td&gt;
&lt;td&gt;0.03&lt;/td&gt;
&lt;td&gt;0.02&lt;/td&gt;
&lt;td&gt;0.01&lt;/td&gt;
&lt;td&gt;0.01&lt;/td&gt;
&lt;td&gt;0.01&lt;/td&gt;
&lt;td&gt;0.02&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.32&lt;/td&gt;
&lt;td&gt;0.20&lt;/td&gt;
&lt;td&gt;0.13&lt;/td&gt;
&lt;td&gt;0.08&lt;/td&gt;
&lt;td&gt;0.08&lt;/td&gt;
&lt;td&gt;0.08&lt;/td&gt;
&lt;td&gt;0.07&lt;/td&gt;
&lt;td&gt;0.07&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4 (train)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.66&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.56&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.45&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.44&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.41&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.41&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.36&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0.58&lt;/td&gt;
&lt;td&gt;0.56&lt;/td&gt;
&lt;td&gt;0.51&lt;/td&gt;
&lt;td&gt;0.47&lt;/td&gt;
&lt;td&gt;0.46&lt;/td&gt;
&lt;td&gt;0.44&lt;/td&gt;
&lt;td&gt;0.39&lt;/td&gt;
&lt;td&gt;0.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;0.55&lt;/td&gt;
&lt;td&gt;0.51&lt;/td&gt;
&lt;td&gt;0.44&lt;/td&gt;
&lt;td&gt;0.41&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;td&gt;0.38&lt;/td&gt;
&lt;td&gt;0.36&lt;/td&gt;
&lt;td&gt;0.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;0.55&lt;/td&gt;
&lt;td&gt;0.48&lt;/td&gt;
&lt;td&gt;0.42&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;td&gt;0.39&lt;/td&gt;
&lt;td&gt;0.37&lt;/td&gt;
&lt;td&gt;0.36&lt;/td&gt;
&lt;td&gt;0.31&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Peak at T=4 across every depth column.&lt;/strong&gt; Day 7's "loops help only in a narrow window centered on training" finding generalizes: no depth I tested has its best accuracy at T≠4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Depth scaling is graceful but the ceiling is low.&lt;/strong&gt; Going from d=2 to d=20 at T=4, accuracy degrades smoothly (0.66 → 0.36), but the absolute numbers stay far from saturation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "deeper input ⇒ more loops" hypothesis does not hold.&lt;/strong&gt; I'd hoped to see T=8 or T=16 begin to dominate at d=20, indicating inference-time scaling could rescue depth. Instead, every depth column peaks at T=4 and decays — same shape as Day 7's digit-count columns, just stretched lower.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;T=8 is unusually competitive at mid-depths.&lt;/strong&gt; At d=4 through d=10, T=8 is within ~1pt of T=4 (sometimes slightly higher). Possibly two adjacent settings of test-time depth around the training value are both near-optimal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Experiment B: fixed-point analysis
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1e79hbd96ki1x96wt0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1e79hbd96ki1x96wt0l.png" alt="fixed-point cosine similarity curve across loop steps and depths"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mean cosine similarity between consecutive hidden states &lt;code&gt;cos(h_t, h_{t-1})&lt;/code&gt; measured at the first-answer-token position, averaged across 4 seeds, 200 samples per depth:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;t&lt;/th&gt;
&lt;th&gt;d=2&lt;/th&gt;
&lt;th&gt;d=4&lt;/th&gt;
&lt;th&gt;d=8&lt;/th&gt;
&lt;th&gt;d=12&lt;/th&gt;
&lt;th&gt;d=16&lt;/th&gt;
&lt;th&gt;d=20&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;td&gt;0.89&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;0.93&lt;/td&gt;
&lt;td&gt;0.91&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.91&lt;/td&gt;
&lt;td&gt;0.91&lt;/td&gt;
&lt;td&gt;0.94&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;0.97&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0.94&lt;/td&gt;
&lt;td&gt;0.94&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;0.92&lt;/td&gt;
&lt;td&gt;0.94&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;0.97&lt;/td&gt;
&lt;td&gt;0.96&lt;/td&gt;
&lt;td&gt;0.95&lt;/td&gt;
&lt;td&gt;0.93&lt;/td&gt;
&lt;td&gt;0.93&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0.998&lt;/td&gt;
&lt;td&gt;0.995&lt;/td&gt;
&lt;td&gt;0.998&lt;/td&gt;
&lt;td&gt;0.996&lt;/td&gt;
&lt;td&gt;0.996&lt;/td&gt;
&lt;td&gt;0.992&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;0.9994&lt;/td&gt;
&lt;td&gt;0.9996&lt;/td&gt;
&lt;td&gt;0.9989&lt;/td&gt;
&lt;td&gt;0.9985&lt;/td&gt;
&lt;td&gt;0.9976&lt;/td&gt;
&lt;td&gt;0.9979&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;0.9998&lt;/td&gt;
&lt;td&gt;0.9998&lt;/td&gt;
&lt;td&gt;0.9998&lt;/td&gt;
&lt;td&gt;0.9997&lt;/td&gt;
&lt;td&gt;0.9995&lt;/td&gt;
&lt;td&gt;0.9996&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three things to note:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fixed-point timing is slightly later than Day 7.&lt;/strong&gt; Day 7 reached ~0.95 by T=2; brackets reach ~0.95 at T=3 and ~0.99 at T=4. About one extra loop step on this metric. Possibly the more complex left-to-right state needs a beat longer to settle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Depth dependence is small.&lt;/strong&gt; d=20 traces almost on top of d=2, again echoing Day 7 (where digit-count had only marginal effect on fixed-point timing). "Harder problem ⇒ slower fixed-point" did not appear.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hidden state stops moving by T=4 (cosine ~0.99) while accuracy starts decaying.&lt;/strong&gt; Same paradox as Day 7: extra loops are computation without information. Either the late-loop perturbations are small but logit-relevant drift away from a converged answer, or this is purely a distribution-shift artifact of training only at T=4.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Comparison with Day 7
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Axis&lt;/th&gt;
&lt;th&gt;Day 7 (addition)&lt;/th&gt;
&lt;th&gt;Day 8 (brackets)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Loop-count peak at T=train (=4)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best accuracy at peak&lt;/td&gt;
&lt;td&gt;100% (all digits)&lt;/td&gt;
&lt;td&gt;66% (d=2), 36% (d=20)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inference-time loop extrapolation&lt;/td&gt;
&lt;td&gt;Hurts&lt;/td&gt;
&lt;td&gt;Hurts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cosine fixed-point arrival&lt;/td&gt;
&lt;td&gt;~T=2&lt;/td&gt;
&lt;td&gt;~T=3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Depth/digit dependence on fixed-point&lt;/td&gt;
&lt;td&gt;Small&lt;/td&gt;
&lt;td&gt;Small&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Training dynamics&lt;/td&gt;
&lt;td&gt;Grokking (sudden phase transition)&lt;/td&gt;
&lt;td&gt;Smooth slow climb&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Day 8 reproduces all the &lt;strong&gt;qualitative&lt;/strong&gt; findings of Day 7. What changes is the &lt;strong&gt;quantitative ceiling&lt;/strong&gt;: at the same parameter budget and the same training compute, structure-tracking caps far below saturation while addition saturates.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Tying back to the three perspectives
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/peppercorn_llm/day-7-openmythos-loop-debate"&gt;Day 7&lt;/a&gt; tested looped transformers against three published views:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Saunshi et al.&lt;/strong&gt; — loops can match deeper fixed-depth networks on algorithmic tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geiping et al. (Huginn)&lt;/strong&gt; — at scale, extra loops give marginal gains&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Micheal Bee&lt;/strong&gt; — loops plateau early at small scale (T=2 fixed-point)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Day 8 adds three more data points to the picture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The "peak at training loop count" pattern persists across qualitatively different algorithmic tasks&lt;/strong&gt; (addition vs. bracket parsing). This is consistent with Saunshi's framing but argues against naive depth-extrapolation at inference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The fixed-point arrives at slightly different times for different tasks.&lt;/strong&gt; Bee's "T=2" appears to be a property of the specific task and training recipe, not a universal property of looped transformers. Brackets need ~T=3-4 to plateau, addition needs ~T=2.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Task structural complexity matters more than loop count.&lt;/strong&gt; At a fixed budget, the ceiling on accuracy is set by something else (model capacity? loss landscape? data efficiency?), not by the number of inference loops. Adding more loops can't compensate.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A useful refinement: &lt;strong&gt;looped transformers carry compute up to a depth bounded by the task's algorithmic complexity and the model's expressive capacity. Beyond that, the hidden state stops moving meaningfully and additional loops are computation without information.&lt;/strong&gt; Day 7 showed this for a task within capacity (addition saturates); Day 8 shows it for a task that bumps against capacity (bracket parsing caps short).&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Technical details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Smoke history (why the task definition changed)
&lt;/h3&gt;

&lt;p&gt;Initial smoke: balanced/imbalanced binary classification, depths 2-10.&lt;br&gt;
Result: 100% accuracy across all depths by step 4,000.&lt;br&gt;
Diagnosis: too many shortcut signals (length parity, open/close count) for the model to learn the stack algorithm — even with mutations that should defeat counting shortcuts. The 2-bit output gives the model no incentive to track position-by-position state.&lt;/p&gt;

&lt;p&gt;Second smoke: first-break-position output, depths 2-20.&lt;br&gt;
Result at 5,000 steps: d=2 100%, d=20 71%, with loss still trending down (0.32 → still falling).&lt;br&gt;
Diagnosis: depth-dependent difficulty visible, room to scale training to expose loop-count effects.&lt;/p&gt;

&lt;p&gt;Lesson worth recording: &lt;strong&gt;output information density matters as much as task structure for studying loop behavior&lt;/strong&gt;. A binary classifier with global-aggregation shortcuts is a weak probe of recurrent depth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Config and hyperparameters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;MythosConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;vocab_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;# 6 brackets + '=' + '$' + space + '-' + '0'-'9'
&lt;/span&gt;    &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_heads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_kv_heads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# GQA
&lt;/span&gt;    &lt;span class="n"&gt;max_seq_len&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;# Day 7 was 32
&lt;/span&gt;    &lt;span class="n"&gt;max_loop_iters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;prelude_layers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;coda_layers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;attn_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gqa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_experts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;# MoE FFN inside recurrent block
&lt;/span&gt;    &lt;span class="n"&gt;n_shared_experts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_experts_per_tok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;expert_dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;lora_rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;rope_theta&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;10000.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total parameters: &lt;strong&gt;3,394,338&lt;/strong&gt; (~3.4M, matches Day 7 to within rounding).&lt;/p&gt;

&lt;p&gt;Training:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimizer: AdamW, betas (0.9, 0.95), wd 0.1&lt;/li&gt;
&lt;li&gt;LR: max 3e-4, warmup 2000 steps, cosine decay to 1e-5&lt;/li&gt;
&lt;li&gt;Grad clip: 1.0&lt;/li&gt;
&lt;li&gt;Batch size: 128&lt;/li&gt;
&lt;li&gt;Max steps: 30000&lt;/li&gt;
&lt;li&gt;dtype: fp32 (same RoPE-complex-buffer reason as Day 7)&lt;/li&gt;
&lt;li&gt;4 seeds {0, 1, 2, 3} in parallel&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data generation
&lt;/h3&gt;

&lt;p&gt;On-the-fly synthetic. For each sample:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sample depth &lt;code&gt;d ∈ {2, 4, 6, 8, 10, 12, 16, 20}&lt;/code&gt; uniformly&lt;/li&gt;
&lt;li&gt;Sample pair count &lt;code&gt;n_pairs ~ U[max(1, d-1), min(2*d, 50)]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Generate balanced parenthesization (random bracket types, nested or sequential)&lt;/li&gt;
&lt;li&gt;With prob 0.5, apply a mutation: delete close (30%), delete open (30%), substitute (40%)&lt;/li&gt;
&lt;li&gt;Compute first-break position with the stack parser; format output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Loss is applied only at positions following &lt;code&gt;=&lt;/code&gt; (i.e., on the 2-digit answer + &lt;code&gt;$&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Experiment A: greedy autoregressive generation, exact 3-token match (position digits + &lt;code&gt;$&lt;/code&gt;). 500 samples per &lt;code&gt;(seed, n_loops, depth)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Experiment B: re-implementation of OpenMythos forward to expose per-loop hidden states. Cosine similarity at the first answer-token position. 200 samples per &lt;code&gt;(seed, depth)&lt;/code&gt;, 32 loop iterations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I'd want to try next
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Increase training-time loop count and re-measure.&lt;/strong&gt; Does the peak track with training depth (suggesting it's purely a distribution-shift artifact) or does extrapolation stay broken?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale model dim while keeping loops fixed.&lt;/strong&gt; Does a 10x bigger model break through the ~66% / ~36% bracket ceiling, or does the structure-tracking task itself need a different inductive bias?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mix tasks in training.&lt;/strong&gt; Train on addition + brackets jointly and see if there's interference or transfer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inject explicit halting (ACT).&lt;/strong&gt; Let the model choose how many loops per token. Does it match the empirical optimum or settle elsewhere?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kyegomez/OpenMythos" rel="noopener noreferrer"&gt;OpenMythos GitHub (Kye Gomez)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://red.anthropic.com/2026/mythos-preview/" rel="noopener noreferrer"&gt;Claude Mythos Preview (Anthropic, 2026-04-07)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2502.17416" rel="noopener noreferrer"&gt;Reasoning with Latent Thoughts (Saunshi et al., ICLR 2025)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2502.05171" rel="noopener noreferrer"&gt;Scaling up Test-Time Compute with Latent Reasoning (Geiping et al., Huginn)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@mbonsign/testing-the-openmythos-hypothesis-emergent-subspace-selectivity-in-looped-transformers-711f8ca0236c" rel="noopener noreferrer"&gt;Testing the OpenMythos Hypothesis (Micheal Bee)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2604.12946" rel="noopener noreferrer"&gt;Parcae — Scaling Laws for Stable Looped Language Models&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Training and evaluation scripts: &lt;a href="https://github.com/SAETAG/dgx-100-experiments/tree/main/days/day08-bracket-matching/scripts" rel="noopener noreferrer"&gt;https://github.com/SAETAG/dgx-100-experiments/tree/main/days/day08-bracket-matching/scripts&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tomorrow: Day 9
&lt;/h2&gt;

&lt;p&gt;Switching gears to something much more personal — handing private chat data to a local model and seeing what it surfaces…!&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>transformers</category>
    </item>
    <item>
      <title>[Day 7] Does Giving an AI More 'Thinking Time' Really Make It Smarter? Training an OpenMythos-Style Mini Model on DGX</title>
      <dc:creator>PEPPERCORN</dc:creator>
      <pubDate>Tue, 19 May 2026 03:17:51 +0000</pubDate>
      <link>https://dev.to/peppercorn_llm/day-7-does-giving-an-ai-more-thinking-time-really-make-it-smarter-training-an-openmythos-style-1epk</link>
      <guid>https://dev.to/peppercorn_llm/day-7-does-giving-an-ai-more-thinking-time-really-make-it-smarter-training-an-openmythos-style-1epk</guid>
      <description>&lt;h1&gt;
  
  
  [Day 7] Does Giving an AI More "Thinking Time" Really Make It Smarter? Training an OpenMythos-Style Mini Model on DGX
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Day 7!&lt;/p&gt;

&lt;p&gt;Reddit kept surfacing this new project called &lt;strong&gt;OpenMythos&lt;/strong&gt; in my feed with "12 days to replicate frontier AI, ASI is near" headlines, and I got curious enough to dig in.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tools used: my home AI machine (DGX Spark) + &lt;a href="https://github.com/kyegomez/OpenMythos" rel="noopener noreferrer"&gt;OpenMythos&lt;/a&gt; (PyTorch reconstruction of the rumored Claude Mythos architecture) + synthetic multi-digit addition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The question: &lt;strong&gt;does giving an AI more "thinking time" (= more recurrent loops at inference) actually make it smarter?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The hype
&lt;/h3&gt;

&lt;p&gt;On 2026-04-07, Anthropic announced &lt;strong&gt;Claude Mythos&lt;/strong&gt;. Press coverage highlights zero-day discovery capabilities — reportedly 271 zero-days in Firefox and a 27-year-old bug in OpenBSD — but the model's architecture and weights remain unreleased. Anthropic kept Mythos itself behind a limited-access coalition (&lt;strong&gt;Project Glasswing&lt;/strong&gt; — AWS, Apple, Microsoft, Google, CrowdStrike, Palo Alto, ~40 organizations) rather than releasing it publicly.&lt;/p&gt;

&lt;p&gt;Twelve days later, Kye Gomez (Swarms) released &lt;strong&gt;OpenMythos&lt;/strong&gt;, a PyTorch reconstruction of the &lt;em&gt;suspected&lt;/em&gt; architecture. The repo is explicit upfront:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"an independent, community-driven theoretical reconstruction based solely on publicly available research and speculation. It is not affiliated with, endorsed by, or connected to Anthropic"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So OpenMythos is &lt;strong&gt;not&lt;/strong&gt; Mythos. It's a hypothesis-in-code: a Recurrent-Depth Transformer (RDT) with MoE FFNs and MLA/GQA attention, capable of being trained from scratch on standard text data. No leaked weights, no distillation.&lt;/p&gt;

&lt;p&gt;Reddit's "ASI is near" framing skips this critical distinction. The interesting question, once you set the hype aside, is whether the &lt;strong&gt;architectural idea&lt;/strong&gt; — recurrent depth — actually works.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note for this article&lt;/strong&gt;: OpenMythos is not Claude Mythos — it's a theoretical reconstruction inspired by looped-transformer research. The experiments below are not "Claude Mythos capability tests" but rather "how does a looped / recurrent-depth structure behave on a small synthetic task."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Three perspectives on looped transformers
&lt;/h3&gt;

&lt;p&gt;Browsing the literature, I found three different studies giving different pictures of how looped transformers behave:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Scale&lt;/th&gt;
&lt;th&gt;Claim&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Saunshi et al. 2025&lt;/strong&gt; (ICLR, research paper)&lt;/td&gt;
&lt;td&gt;tens of M params, synthetic&lt;/td&gt;
&lt;td&gt;Loops work: k layers looped L times approximately matches kL-layer fixed-depth, on addition / p-hop induction / math&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Geiping et al. 2025&lt;/strong&gt; (Huginn, research paper)&lt;/td&gt;
&lt;td&gt;3.5B params, 800B tokens&lt;/td&gt;
&lt;td&gt;Task-dependent: at scale on natural-language benchmarks, gains can be marginal (T=4 → T=32 only +1.82 points on GSM8K), though effects vary by task and compute regime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Micheal Bee 2026-04&lt;/strong&gt; (Medium, independent experiment blog)&lt;/td&gt;
&lt;td&gt;17M params, 12 GPU-hours on RTX 5070 Ti&lt;/td&gt;
&lt;td&gt;Loops plateau at T=2 in this small-scale setup: hidden state reaches a fixed-point that subsequent iterations cannot escape&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Theory, large-scale empirics, and an independent solo replication give different pictures. I wanted to add a fourth data point from my own DGX Spark on a clean, controlled task — multi-digit addition.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I'd hoped to see
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Does training-time accuracy phase-transition (grok) at some step? (Saunshi 3-stage prediction)&lt;/li&gt;
&lt;li&gt;Does test-time loop count matter? At what point does it stop helping?&lt;/li&gt;
&lt;li&gt;Does the hidden state actually keep evolving across loops, or does it hit a fixed-point early? (the Bee question)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Headline finding
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Loops help, but only within a narrow window centered on the training loop count.&lt;/strong&gt; With training-time &lt;code&gt;max_loop_iters=4&lt;/code&gt;, accuracy peaks at exactly T=4 (100% across all digit counts) and decays in &lt;em&gt;both&lt;/em&gt; directions — fewer loops underthink, more loops overthink.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bee's "T=2 fixed-point" reproduced.&lt;/strong&gt; Cosine similarity between consecutive hidden states jumps from ~0.72 to ~0.95 at T=2, then climbs slowly to ~0.99 by T=4 and stays flat through T=32.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Striking per-seed grokking variance.&lt;/strong&gt; Same hyperparameters, four seeds: seeds 1 and 3 solve 5-digit addition by step 4,000; seed 2 takes 10,000; seed 0 stalls at &amp;lt;10% until step 16,000, then jumps to 100%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No depth extrapolation in this setup.&lt;/strong&gt; Saunshi's claim that training at T=4 should generalize to deeper T at inference does &lt;em&gt;not&lt;/em&gt; reproduce here — instead, T&amp;gt;4 hurts.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌀 What is a "looped" transformer?
&lt;/h2&gt;

&lt;p&gt;A standard transformer (GPT-4, Llama, most local LLMs) routes input tokens through a stack of distinct layers, each used exactly once per forward pass. To make it "think deeper," you stack more layers — increasing parameter count.&lt;/p&gt;

&lt;p&gt;A looped transformer reuses &lt;strong&gt;the same&lt;/strong&gt; parameters across multiple iterations. The model has a &lt;code&gt;Prelude → Recurrent Block × T → Coda&lt;/code&gt; structure: a few standard layers up front, then one block iterated T times with input injection at every step, then a few more standard layers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input tokens
   ↓
[Prelude P]          — standard layers, run once
   ↓
[Recurrent Block R]  — one block looped T times
   ↑_______↓          h_{t+1} = A·h_t + B·e + Transformer(h_t, e)
   ↓
[Coda C]             — standard layers, run once
   ↓
Output logits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At each loop iteration &lt;code&gt;t&lt;/code&gt;, the hidden state updates via the LTI injection rule, and the encoded input &lt;code&gt;e&lt;/code&gt; (Prelude output) is re-injected to keep the original signal alive across arbitrary depth. The injection parameters are constrained so that spectral radius ρ(A) &amp;lt; 1, which prevents divergence over many loops (Parcae stability framework).&lt;/p&gt;

&lt;p&gt;The key claim: &lt;strong&gt;more loops at inference = deeper reasoning, without adding parameters&lt;/strong&gt;. This is conceptually analogous to chain-of-thought scaling — except the "thinking" happens in continuous latent space rather than discrete token space.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 Experimental setup
&lt;/h2&gt;

&lt;p&gt;I trained a deliberately tiny OpenMythos variant on multi-digit addition. The model is small enough to run 4 seeds in parallel on a single GPU but large enough to exhibit the looped-transformer phenomena.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenMythos tiny (3.4M params)
  ↓
Train 4 seeds in parallel, 30k steps each, fp32 on DGX Spark (GB10)
  ↓
Experiment A: greedy autoregressive accuracy
              loops ∈ {1, 2, 4, 8, 16, 32}  ×  digits ∈ {2, 3, 4, 5}
  ↓
Experiment B: cosine similarity between consecutive hidden states
              ⇒ does the recurrent block reach a fixed-point?
  ↓
Compare against Saunshi / Huginn / Bee
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Model config
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nc"&gt;MythosConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;vocab_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;# digits 0-9 + '+', '=', pad, eos
&lt;/span&gt;    &lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_heads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_kv_heads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;# GQA
&lt;/span&gt;    &lt;span class="n"&gt;max_seq_len&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_loop_iters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;# training depth; inference varies
&lt;/span&gt;    &lt;span class="n"&gt;prelude_layers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;coda_layers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;attn_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gqa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_experts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;# MoE FFN inside recurrent block
&lt;/span&gt;    &lt;span class="n"&gt;n_shared_experts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n_experts_per_tok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;expert_dim&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;lora_rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;# depth-wise LoRA per loop step
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total parameters: &lt;strong&gt;3,386,658&lt;/strong&gt; (~3.4M).&lt;/p&gt;

&lt;h3&gt;
  
  
  Data
&lt;/h3&gt;

&lt;p&gt;On-the-fly synthetic addition. Operands are uniformly sampled from &lt;code&gt;[10^(d-1), 10^d - 1]&lt;/code&gt; for digit count &lt;code&gt;d ∈ {2, 3, 4, 5}&lt;/code&gt;. Sequence format &lt;code&gt;"A+B=R$"&lt;/code&gt;, where &lt;code&gt;R = str(A+B)[::-1]&lt;/code&gt; (reverse-order answer, following Saunshi's convention so left-to-right autoregressive generation can carry digits naturally).&lt;/p&gt;

&lt;p&gt;Loss is applied only at positions following the &lt;code&gt;=&lt;/code&gt; token (i.e., on the answer tokens).&lt;/p&gt;

&lt;h3&gt;
  
  
  Training
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Optimizer: AdamW, betas (0.9, 0.95), wd 0.1&lt;/li&gt;
&lt;li&gt;LR: max 3e-4, warmup 2000 steps, cosine decay to 1e-5&lt;/li&gt;
&lt;li&gt;Grad clip: 1.0&lt;/li&gt;
&lt;li&gt;Batch size: 128&lt;/li&gt;
&lt;li&gt;Max steps: 30000&lt;/li&gt;
&lt;li&gt;dtype: &lt;strong&gt;fp32&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Initially I tried bf16 to use the GB10 efficiently, but OpenMythos stores RoPE frequencies as &lt;code&gt;complex64&lt;/code&gt; buffers, and &lt;code&gt;model.to(bfloat16)&lt;/code&gt; silently drops the imaginary part, breaking attention. For a 3.4M-param model on 128 GB of unified memory, fp32 is fine — the bottleneck is not memory but parallel scheduling.&lt;/p&gt;

&lt;p&gt;Four seeds {0, 1, 2, 3} run in parallel on the same GPU. Per-seed throughput drops to ~12K tok/s (vs ~50K solo), but wall-clock time for all four is approximately equivalent to one solo run.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Experiment A: accuracy heatmap
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62vulnao2x15psie2uv8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62vulnao2x15psie2uv8.png" alt="accuracy heatmap of OpenMythos addition across loop counts and digit counts" width="800" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mean fully-correct rate across 4 seeds, 500 eval samples per condition:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Inference loops&lt;/th&gt;
&lt;th&gt;d=2&lt;/th&gt;
&lt;th&gt;d=3&lt;/th&gt;
&lt;th&gt;d=4&lt;/th&gt;
&lt;th&gt;d=5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.38 ± 0.12&lt;/td&gt;
&lt;td&gt;0.19 ± 0.09&lt;/td&gt;
&lt;td&gt;0.09 ± 0.07&lt;/td&gt;
&lt;td&gt;0.02 ± 0.02&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.53 ± 0.17&lt;/td&gt;
&lt;td&gt;0.50 ± 0.12&lt;/td&gt;
&lt;td&gt;0.16 ± 0.08&lt;/td&gt;
&lt;td&gt;0.21 ± 0.16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4 (train)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.00&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.00&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0.98 ± 0.01&lt;/td&gt;
&lt;td&gt;0.98 ± 0.01&lt;/td&gt;
&lt;td&gt;0.94 ± 0.03&lt;/td&gt;
&lt;td&gt;0.86 ± 0.08&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;0.91 ± 0.04&lt;/td&gt;
&lt;td&gt;0.91 ± 0.05&lt;/td&gt;
&lt;td&gt;0.75 ± 0.10&lt;/td&gt;
&lt;td&gt;0.56 ± 0.16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;0.62 ± 0.12&lt;/td&gt;
&lt;td&gt;0.65 ± 0.13&lt;/td&gt;
&lt;td&gt;0.45 ± 0.13&lt;/td&gt;
&lt;td&gt;0.26 ± 0.17&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Peak is exactly at training-time loop count (T=4), 100% across all digit counts.&lt;/li&gt;
&lt;li&gt;One step of inference-time extrapolation (T=8) is near-peak but already shows degradation at d=5 (86%).&lt;/li&gt;
&lt;li&gt;Beyond T=8, accuracy collapses monotonically. At T=32, even 2-digit addition drops to 62%.&lt;/li&gt;
&lt;li&gt;Under-looping (T=1, T=2) hurts more at higher digit counts, consistent with depth being needed to chain carries.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Experiment B: fixed-point analysis
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2lcx3dpp8c8s4e4dab63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2lcx3dpp8c8s4e4dab63.png" alt="fixed-point cosine similarity curve across loop steps" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mean cosine similarity between consecutive hidden states &lt;code&gt;cos(h_t, h_{t-1})&lt;/code&gt; over answer positions, averaged across 4 seeds, 200 samples per digit:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;t&lt;/th&gt;
&lt;th&gt;d=2&lt;/th&gt;
&lt;th&gt;d=3&lt;/th&gt;
&lt;th&gt;d=4&lt;/th&gt;
&lt;th&gt;d=5&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;0.711&lt;/td&gt;
&lt;td&gt;0.726&lt;/td&gt;
&lt;td&gt;0.745&lt;/td&gt;
&lt;td&gt;0.744&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.961&lt;/td&gt;
&lt;td&gt;0.967&lt;/td&gt;
&lt;td&gt;0.957&lt;/td&gt;
&lt;td&gt;0.946&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0.985&lt;/td&gt;
&lt;td&gt;0.986&lt;/td&gt;
&lt;td&gt;0.977&lt;/td&gt;
&lt;td&gt;0.971&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.993&lt;/td&gt;
&lt;td&gt;0.992&lt;/td&gt;
&lt;td&gt;0.986&lt;/td&gt;
&lt;td&gt;0.983&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;0.999&lt;/td&gt;
&lt;td&gt;0.999&lt;/td&gt;
&lt;td&gt;0.998&lt;/td&gt;
&lt;td&gt;0.996&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;0.9995&lt;/td&gt;
&lt;td&gt;0.9996&lt;/td&gt;
&lt;td&gt;0.9992&lt;/td&gt;
&lt;td&gt;0.998&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;32&lt;/td&gt;
&lt;td&gt;0.9995&lt;/td&gt;
&lt;td&gt;0.9996&lt;/td&gt;
&lt;td&gt;0.999&lt;/td&gt;
&lt;td&gt;0.998&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Bee's T=2 fixed-point claim is reproduced in spirit but not literally: cosine similarity jumps to ~0.95 at T=2 (vs. Bee's near-1.0), then asymptotes to ~0.99 by T=4 and stays flat through T=32.&lt;/p&gt;

&lt;p&gt;The difference vs. accuracy is telling: &lt;strong&gt;hidden state is effectively static (by cosine similarity) from T=4 onwards, yet accuracy collapses at T=16-32&lt;/strong&gt;. Two non-exclusive interpretations: (a) overthinking — late loops drift away from a converged solution; (b) distribution shift — training used T=4, so T&amp;gt;&amp;gt;4 is simply an out-of-distribution use of the model. Worth noting that cosine similarity ≈ 1 doesn't prove the hidden state is doing nothing — small logit-relevant deltas may still accumulate.&lt;/p&gt;

&lt;p&gt;Digit-count dependence on fixed-point timing is small (d=5 lags d=2 by ~0.01 in cosine sim). "Harder problems take more loops to converge" is &lt;em&gt;not&lt;/em&gt; observed here — they converge at the same rate but the converged state is just less accurate at higher digit counts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: training dynamics
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6z2j3kgsk8jpcdm3iq3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6z2j3kgsk8jpcdm3iq3i.png" alt="training loss and teacher-forced accuracy curves per seed" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most striking thing in the training curves is &lt;strong&gt;seed-dependent grokking timing&lt;/strong&gt;. Four runs of identical hyperparameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;seed 1: loss → 0 by step 3,000, all digits ≥88% by step 4,000&lt;/li&gt;
&lt;li&gt;seed 3: loss → 0 by step 4,000, all digits ≥87% by step 4,000&lt;/li&gt;
&lt;li&gt;seed 2: stuck at loss ~0.35 plateau until step 8,000, then collapses to 0 by step 10,000; d=4/5 jump from &amp;lt;10% to 99% in 2,000 steps&lt;/li&gt;
&lt;li&gt;seed 0: stuck at loss ~0.30 plateau until step 15,000, then collapses; d=4 groks at step 12,000-14,000, d=5 groks at step 16,000&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is textbook Saunshi-style three-stage grokking (memorization → in-distribution → systematic), with the third-stage trigger varying by a factor of &lt;strong&gt;4x in step count&lt;/strong&gt; purely on random init. The largest seed gap (seed 0 vs. seed 1) is ~12,000 steps, roughly 1 hour of wall-clock on this DGX.&lt;/p&gt;

&lt;p&gt;If you trained a single seed and stopped early, you might conclude "OpenMythos can't generalize beyond d=3" — which would be wrong. The architecture &lt;em&gt;can&lt;/em&gt; solve all 4 digit buckets; some random seeds just need much longer to find the systematic-generalization solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 What this means for the three perspectives
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Where my data point lands
&lt;/h3&gt;

&lt;p&gt;My single-DGX small-scale result lands somewhere between Bee and a partial refutation of Saunshi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bee's fixed-point at small T is reproduced.&lt;/strong&gt; Hidden state effectively stops evolving by T=4 (cosine sim ≥ 0.99) and certainly by T=8.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saunshi's depth-extrapolation does NOT reproduce.&lt;/strong&gt; Inference at T &amp;gt; train_T does &lt;em&gt;not&lt;/em&gt; improve accuracy — it harms it. T=8 is already at 86% on d=5 (vs. 100% at T=4), and T=32 collapses to 26%. The "train at depth k, infer at depth k·L" recipe assumes the recurrent block has learned to keep refining; in my setup it has not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Huginn's limited-gain finding is consistent at small scale.&lt;/strong&gt; Extra inference loops give negative ROI rather than diminishing positive ROI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New observation: seed-dependent grokking with up to 12K-step variance.&lt;/strong&gt; This is an under-emphasized variable in the public looped-transformer discourse — single-seed studies (Bee's solo replication, individual rows in Saunshi's tables) may be substantially under- or over-estimating typical behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reconciliation attempt
&lt;/h3&gt;

&lt;p&gt;Theory (Saunshi), large-scale empirics (Huginn), and independent replication (Bee) may not actually be in contradiction — they may be measuring different facets of the same phenomenon at different scales:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Saunshi&lt;/strong&gt;: shows loops &lt;em&gt;can&lt;/em&gt; work on the right kind of problem (algorithmic, depth-bounded reasoning) at the right kind of scale (small synthetic).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Huginn&lt;/strong&gt;: shows that loops trained at 3.5B / 800B token scale on natural-language data give only marginal gains on a benchmark (GSM8K) that already favors CoT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bee&lt;/strong&gt;: shows that within a particular small-scale training recipe, the recurrent block's hidden state stops evolving very early in inference.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These three findings are compatible with a unified picture: &lt;strong&gt;loops carry compute, but only up to a depth bounded by the task's algorithmic complexity and the model's expressive capacity&lt;/strong&gt;. Beyond that depth, the hidden state stops moving meaningfully, and additional loops are computation without information.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I'd watch next
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Increase loop count during training (here I used 4) and see if the inference-time scaling extends further&lt;/li&gt;
&lt;li&gt;Try ACT halting more aggressively to see how the model self-regulates loop depth per token&lt;/li&gt;
&lt;li&gt;Add task heterogeneity (mix p-hop induction or parity) to test whether the fixed-point timing varies by problem class&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Technical details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reproducing this experiment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/kyegomez/OpenMythos
&lt;span class="nb"&gt;cd &lt;/span&gt;OpenMythos
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Data, training, evaluation scripts (this Day 7 folder):&lt;/span&gt;
python scripts/train.py &lt;span class="nt"&gt;--seed&lt;/span&gt; 0 &lt;span class="nt"&gt;--max_steps&lt;/span&gt; 30000
python scripts/eval_accuracy.py &lt;span class="nt"&gt;--seeds&lt;/span&gt; 0 1 2 3
python scripts/eval_fixedpoint.py &lt;span class="nt"&gt;--seeds&lt;/span&gt; 0 1 2 3
python scripts/plot.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The training and evaluation scripts are at &lt;a href="https://github.com/SAETAG/dgx-100-experiments/tree/main/days/day07-openmythos-loop-debate/scripts" rel="noopener noreferrer"&gt;https://github.com/SAETAG/dgx-100-experiments/tree/main/days/day07-openmythos-loop-debate/scripts&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What went wrong (and was fixed)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;bf16 broke complex RoPE buffer&lt;/strong&gt;: switched to fp32; fine at 3.4M parameters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initial training-time max_loop_iters too small&lt;/strong&gt;: kept at 4 per Saunshi's recipe; future experiments could vary this&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Greedy generation is slow at high loop counts&lt;/strong&gt;: each batch repeats &lt;code&gt;n_loops&lt;/code&gt; forward passes through the recurrent block; for loops=32 this is non-trivial&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hyperparameter choices: why these
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dim=256, expert_dim=512, 1 prelude / 1 coda layer&lt;/code&gt;: smallest config that still exhibits looping behavior; matches Saunshi's scale&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n_experts=4&lt;/code&gt;: enough to demonstrate MoE routing without bloating params&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lora_rank=8&lt;/code&gt;: depth-wise LoRA lets each loop iteration adapt slightly without breaking weight-sharing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_seq_len=32&lt;/code&gt;: tight bound — d=5 addition fits in ~18 chars&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kyegomez/OpenMythos" rel="noopener noreferrer"&gt;OpenMythos GitHub (Kye Gomez)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://red.anthropic.com/2026/mythos-preview/" rel="noopener noreferrer"&gt;Claude Mythos Preview (Anthropic, 2026-04-07)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.anthropic.com/glasswing" rel="noopener noreferrer"&gt;Project Glasswing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2502.17416" rel="noopener noreferrer"&gt;Reasoning with Latent Thoughts (Saunshi et al., ICLR 2025)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2502.05171" rel="noopener noreferrer"&gt;Scaling up Test-Time Compute with Latent Reasoning (Geiping et al., Huginn)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@mbonsign/testing-the-openmythos-hypothesis-emergent-subspace-selectivity-in-looped-transformers-711f8ca0236c" rel="noopener noreferrer"&gt;Testing the OpenMythos Hypothesis (Micheal Bee)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2604.12946" rel="noopener noreferrer"&gt;Parcae — Scaling Laws for Stable Looped Language Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2604.07822" rel="noopener noreferrer"&gt;Loop, Think, &amp;amp; Generalize (Implicit Reasoning in Recurrent-Depth Transformers)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tomorrow: Day 8
&lt;/h2&gt;

&lt;p&gt;A follow-up to Day 7, pushing looped thinking one step further into something harder…!&lt;/p&gt;

&lt;h1&gt;
  
  
  100ExperimentsWithDGX #LocalLLM
&lt;/h1&gt;

</description>
      <category>localllm</category>
      <category>ai</category>
      <category>dgxspark</category>
      <category>transformers</category>
    </item>
  </channel>
</rss>
