--- title: 'Lex: LLM dictionary on RPi5' date: 2026-09-20 layout: post --- Year of our Lord 2026. LLMs are everywhere. Built Lex, a context-aware dictionary.
|
|
+--------------+--------+-------------+---------------------+----------+ | Model | Tokens | Tok/s (μ±σ) | Time s (Med/Range) | RAM (MB) | +--------------+--------+-------------+---------------------+----------+ | Qwen 2.5 3B | 114.0 | 5.22 ± 0.31 | 21.79 (19.39-25.20) | 3,235.22 | | Qwen 2.5 7B | 104.5 | 2.09 ± 0.07 | 49.27 (45.50-52.98) | 7,335.18 | | Phi 3.5 3.8B | 128.2 | 2.06 ± 0.10 | 71.87 (48.67-72.37) | 3,922.55 | | LLaMA 3.1 8B | 115.5 | 2.01 ± 0.08 | 57.10 (53.95-66.09) | 7,873.52 | | Mistral 7B | 106.6 | 1.67 ± 0.13 | 64.25 (57.85-66.86) | 7,535.61 | +--------------+--------+-------------+---------------------+----------+Larger models caught nuances smaller ones missed, but definitions weren't consistently better. Gemma 2 9B generated empty responses due to chat template bug; fixed, but 7.8 GB RAM usage didn't justify re-running benchmarks. Qwen 2.5 3B struggled with formality level, but produced tighter, faster definitions at 3.2 GB RAM and 2 GB storage. Flashed OpenBSD onto the Toshiba micro SD card without man, game, and X file sets. Kept comp set to build lex-llm. lex-llm requires just over 2.2 GB to build. 2.2 GB left on the disk. Disabled boot-time library re-linking and purged /usr/share/relink to reclaim a further 450 MB. Stripped llama.cpp to essentials during the build to yield a 12.9 MB executable: ``` cmake -S $(LLAMA_SRC_DIR) -B $(LLAMA_BUILD) \ -DBUILD_SHARED_LIBS=OFF \ -DGGML_OPENMP=OFF \ -DGGML_VULKAN=OFF \ -DLLAMA_BUILD_SERVER=OFF \ -DLLAMA_BUILD_UI=OFF # + misc size-reduction flags, omitted cmake --build $(LLAMA_BUILD) --config Release -j$$(sysctl -n hw.ncpu) ``` Backed up the executable and reinstalled OS removing also the comp set. OS + lex-llm + model now fits: ``` Filesystem Size Used Avail Capacity Mounted on /dev/sd0a 3.5G 2.5G 815M 76% / mfs:76650 61.9M 5.0K 58.8M 1% /tmp mfs:29597 15.4M 87.0K 14.6M 1% /var/run mfs:35201 30.9M 113K 29.3M 1% /var/log ``` Worked well for two weeks. Then the file system corrupted twice within a week. Disk had 400 MB+ free space; badblocks revealed no bad sectors. fsck_ffs reported a partially truncated inode indicating an interrupted write. Power-induced link glitch perhaps—no way to know now. Hunted down anything that wrote to disk (cron, ntpd, sshd). Mounted /dev (sshd pty allocation) to mfs. Moved cron's log to /var/log/cron and symlinked ntpd.drift to /var/run/ntpd.drift. Assigned a static IP and disabled almost all the daemons (dhcpleased, resolvd, slaacd). Placed a /root/.marker to catch anything I might have missed. / is now read-only: ``` /dev/sd0a on / type ffs (local, noatime, wxallowed, read-only) mfs:69255 on /dev type mfs (asynchronous, local, nosuid, size=32768 512-blocks) mfs:75124 on /tmp type mfs (asynchronous, local, nodev, nosuid, size=131072 512-blocks) mfs:15499 on /var/log type mfs (asynchronous, local, nodev, nosuid, size=65536 512-blocks) mfs:14160 on /var/run type mfs (asynchronous, local, nodev, nosuid, size=32768 512-blocks) ``` Deployment went smoothly, except the RPi5 wouldn't boot without a serial adapter plugged into the JST port; RX pin floated with no internal pull-up enabled. Resolved by adding an external 10 kΩ pull-up (RX to 3.3 V). Security: PGP authentication, lockfile semaphores, chroot, pledge + unveil guard the components. Bringing lex-llm into home network has inherent risks. In addition to the hardened OS, configured packet filter to block network scans, access to other hosts: ``` set skip on lo block all block out on $net_if to $home_net # DNS lookups for ntpd pass out on $net_if proto { tcp, udp } to $router port domain # outbound ssh to VPS pass out on $net_if inet proto tcp from ($net_if) to $vps port ssh # ntpd constraints check pass out on $net_if proto udp to ! $home_net port ntp pass out on $net_if proto tcp to ! $home_net port https # inbound SSH from local network management hosts pass in on $net_if inet proto tcp from $home_net to ($net_if) port ssh ``` End of line. Source: b904341