Building KRXY — Part 2: Building the First Raspberry Pi AI Node
What the first Pi, the Hailo accelerator and its USB boot disk actually did on 24 October 2026.

Part 1 was the plan. The diagrams were coherent, and the hardware list was specific enough to order from. None of that answered the first practical question: could a Raspberry Pi 5 and an AI accelerator become a remotely managed worker, and could I say what that machine had actually done?
This part is the first day that question had an answer. The day is 24 October 2026. The record is a commissioning sheet, a node runbook, and the decisions that led up to the order. Where those records disagree with Part 1, I follow the records.
From the plan to an order
On 16 September 2026 the reference design was a Raspberry Pi 5, preferably with 16 GB of system RAM, a Raspberry Pi AI HAT+ 2, active cooling, a USB-attached SSD, and Gigabit Ethernet. The reason for USB was already fixed. The Pi 5 has one external PCIe connection. The HAT uses it, so the SSD cannot take the same connection.
The next day the purchase was staged. One physical worker, extra workers simulated, and my existing development Mac as a temporary control plane. The RAM target for that first board was cut to 8 GB, on the argument that the HAT has its own memory and that a larger board should wait for a measurement. A management Pi was left for later. Combining the coordinator and the worker on one board would have made the control plane vanish every time I rebooted the worker.
On 18 October the order went the other way on RAM. The board ordered was a Raspberry Pi 5 with 16 GB, plus the AI HAT+ 2. Storage, the enclosure, cooling and the power supply were still only planned. There was no commissioned machine that day. The repository, as recovered that morning, held the September documents and no application code. Choosing 16 GB was a procurement decision. It was not evidence that 8 GB would have failed.

What was actually on the bench
The machine that was measured on 24 October was a Raspberry Pi 5 Model B, revision 1.1. Linux reported four aarch64 processors and a MemTotal of 16,607,536 kB, about 15.8 GiB. That is how a 16 GB board usually appears. It is the system RAM. It is not the accelerator's memory.
The HAT enumerated on PCIe as a Hailo-10H. The link on that boot was 8.0 GT/s, one lane, so the single external connection was running at a PCI Express 3.0 rate. The runtime named the architecture HAILO10H and the firmware 5.1.1. Raspberry Pi's product page for the AI HAT+ 2, product code SC2166, specifies a Hailo-10H, 8 GB of memory on the HAT, and 40 TOPS of INT4 inference. I am quoting that page. The commissioning tools did not print a measurement of those 8 GB, and they did not print a TOPS figure. The 8 GB is device memory. It does not appear in the Pi's 16 GB.
The boot disk identified itself as a Samsung PM871b M.2 2280, 256 GB. That model is a SATA drive, not an NVMe drive. The kernel saw it through a Realtek RTL9210 USB bridge, at 5 Gbit/s, with the UAS driver. The root filesystem was ext4 on that disk, and the boot firmware partition was on it too. At 15:26 the filesystem reported 9.3 GB used and 216 GB free, on a volume of about 235 GB. The planning documents had preferred a 1 TB NVMe SSD. Part 1 named the enclosure as a fanxiang MD87. The commissioning sheet records the bridge chip and the Samsung model. It does not record the retail name of the enclosure, and it does not record a price. The vendor's advertised speed for that enclosure was not what the USB link negotiated.
The cooler, the supply and the board case are official Raspberry Pi parts. The Active Cooler, product code SC1148, is an aluminium heatsink and a blower that plugs into the Pi 5 fan header. Raspberry Pi rates that fan at up to 8,000 RPM. The supply is SC1149, the white UK 27 W USB-C unit, specified at 5.1 V and 5 A. The case is SC1159, red and white. A distributor order dated 28 October 2026 bought three coolers, two supplies and two cases. The unit prices, before VAT, were £3.79, £9.09 and £7.58. Shipping was not charged, and the VAT on the order was £8.94. That order is four days after these measurements, and the quantities are more than one node, so it identifies the parts bought for the machines. It is not a receipt for the single board that booted on 24 October, and the Pi and the HAT are not on it.
A fan was already present on the 24th. Once the agent that could read it was the one actually running, telemetry stored a speed near 2,970 RPM, well under the Active Cooler's stated maximum. The commissioning sheet does not name the part. Across the temperature samples that day the Pi's throttle flag stayed 0x0, including the undervoltage bit. That is a firmware report from those samples. It is not a measurement of watts drawn from SC1149. The sheet also does not say the red and white case was fitted. The HAT occupies the top of the board, and the Active Cooler is the part sold for a Pi that is not using the case's own fan.
The network fact is smaller than the plan. The plan preferred Ethernet. On this day the address was on Wi-Fi. The Ethernet interface was present and had no IPv4 address. I am leaving the addresses themselves out of a public post.
There was no recovery microSD. A failed boot disk would have meant imaging a card and moving the Pi onto it. Copies of boot files are not a disk image.
| Component | What the record identifies | Role on 24 October | Cost |
|---|---|---|---|
| Computer | Raspberry Pi 5 Model B Rev 1.1, 16 GB, four Arm cores | The worker | Not recorded |
| Accelerator | Raspberry Pi AI HAT+ 2, Hailo-10H, firmware 5.1.1 | Inference on the one PCIe link | Not recorded |
| Accelerator memory | 8 GB on the HAT, Raspberry Pi's specification | Device memory, separate from system RAM | Not recorded |
| Boot disk | Samsung PM871b 256 GB, M.2 SATA | Root and boot firmware, over USB | Not recorded |
| USB bridge | Realtek RTL9210, 5 Gbit/s, UAS | The path to that disk | Not recorded |
| Cooling | Raspberry Pi Active Cooler, SC1148 | About 2,970 RPM on the evening of 24 October | £3.79 each, before VAT, three on the 28 October order |
| Power | Raspberry Pi 27 W USB-C supply, SC1149, 5.1 V / 5 A, UK plug | No throttle flag in that day's samples | £9.09 each, before VAT, two on the 28 October order |
| Board case | Raspberry Pi 5 case, SC1159, red and white | Not recorded as fitted on 24 October | £7.58 each, before VAT, two on the 28 October order |
| Network | Wi-Fi associated; Ethernet had no address | How the node reached the Mac | Not recorded |
| Control plane | The existing development Mac | Registry, jobs, and the database | Already owned |
| Recovery card | None | A gap, not a component | Not recorded |

The software that made it a node
Raspberry Pi OS on the board was Debian 13 (trixie), kernel 6.18.50+rpt-rpi-2712.
The Hailo software had a fork I had to get right before anything ran. hailo-all is the older Hailo-8 stack and conflicts with the HAT+ 2 packages. The install was dkms and hailo-h10-all 5.1.1 from the Raspberry Pi archive, plus the Hailo GenAI package at the same 5.1.1 version. A newer GenAI package existed. It was left alone, because it was not the release paired with that driver. Nothing in the record says I installed the wrong stack and then recovered. The constraint was known, and the paired versions are what landed on the machine.
hailo-ollama is the local server that loads a compiled Hailo model and exposes a small HTTP API. It was bound to 127.0.0.1:8000 on the Pi, so the model service was not on the LAN. The KRXY agent, running as the user krxy, called that address. The Mac kept the control plane. The Pi did not get a copy of the Mac's SSH key, and it did not get the platform environment file. The enrolment token was removed after the first successful enrolment. The node key stayed on the Pi. Replacing that key would have been a different node.
The model was not trained for KRXY. The catalogue id was qwen2.5-instruct:1.5b: Qwen2.5-Instruct at 1.5 billion parameters, quantised Q4_0, compiled as a Hailo HEF. The pull log recorded 2,359,716,464 bytes. The installed HEF's compiled context is 2,048 tokens. The manifest's licence field was empty. I can say what was loaded. I cannot treat that file as a model this project trained.

The day, in the order it happened
The sheet does not give a delivery date between the 18 October order and this day. It does record an idle CPU temperature of 46.1°C taken before the HAT was fitted. There is no matching idle reading from later, with the HAT on and the services stopped.
By early afternoon the provisioning log and the model-pull log had been written. At 15:14 the provisioner recorded that it was finished, and the model was marked pulled. A ten-minute soak then sent 717 sequential chats to the local server. The prompt was Reply with the digit 1., with a limit of eight predicted tokens. There were no errors. Wall-clock latency around those HTTP calls was 0.688 s minimum, 0.703 s median, and 1.44 s maximum. Sampled CPU temperature was 58.7–65.3°C, the throttle flag stayed clear, and about 15.5 GiB of system memory stayed available. That median is the latency of this tiny request. It is not a tokens-per-second result, and it is not a number I would quote for a normal prompt.
At 15:20 the Pi was rebooted. hailo-ollama was back at 15:20:09 and the agent at 15:20:18. Provisioning did not run again, and the model was not downloaded again. /dev/hailo0 came up owned by root:render. The account krxy is in the render group, which is what allows it to open the device. Heartbeats resumed, and the node identity was the same one as before the reboot.
A local chat after that boot, the same short prompt, returned 1. The runtime reported two evaluated tokens, a stop reason of stop, and a total duration of about 0.66 s. The wall clock around the call was 0.705 s. During the request the server held the Hailo device open.
The control plane then assigned work. One job completed with the marker KRXY-HAIL-OK. A second, after the reboot, completed with KRXY-BOOT-OK. The second reported about 14.3 s of wall time and about 1.3 s in the accelerator field. The wall time includes the model load after boot. Both results were stored as completed. Verification was unsupported, reserved credits were zero, and no contribution row was written. Completed means the node returned a result. It does not mean a validator accepted it.
Later that afternoon a browser session on the Mac asked the node, through KRXY, what three plus three is. The reply that came back was "The answer to your question is 6." The prompt had also asked the model to mention a marker. The stored reply did not contain it.

What went wrong on the same day
The first was a permission inherited from the GenAI package. Its install makes the model directory world-writable so a pull can store files. After the reboot, hailo-ollama logged that it could not create hailort.log, and it kept serving requests anyway. That evening the directory was set to mode 0750, owned by krxy. The log warning did not return. A world-writable model store on a machine that accepts other people's prompts is a bad default, even on a lab bench.
The second was which process was the agent. At 21:27 the systemd unit was enabled and inactive. It had been stopped at 18:08. Two processes started at 18:16 by a detached shell were still heartbeating. The running image was agent 0.2.0-hailo. The file on disk was already 0.3.0-hailo. The control plane stored the old version, and it stored the fan as absent, with no speed. Inference itself was fine: hailo-ollama was the process systemd was already supervising. At 21:49 a restore script checked the on-disk version, signalled the detached processes, and let systemd start the unit. A further restart left a single agent in that unit, reporting 0.3.0-hailo and a fan speed near 2,970 RPM. The node identity did not change. The earlier "fan absent" line was a stale process, not a missing cooler.
The third showed up when the reply was longer than the soak prompt. The agent in use that afternoon limited output to 64 tokens. A longer generation the same night stopped on that allowance and ended in the middle of a line. At 23:04 that silent cap was removed. From then on, the platform recorded the server's own stop reason. A missing reason is treated as "length" only when the measured output actually meets the allowance. The same evening, a generation longer than about 30 seconds had also stopped the heartbeats, so the node looked offline while it was working. The following agent build heartbeats on a side thread. During a 28.8 s reply the newest sample stayed inside 15 seconds.
None of these were theoretical. Each one left the machine looking healthier in a status page than it was.
What that day proved
By the end of 24 October I had one physical worker with a recorded identity.
- It booted from the USB disk, with the Hailo driver and both services coming back after a reboot.
- The accelerator was visible as
/dev/hailo0, firmware 5.1.1, and a local server answered the selected HEF. - The Mac could assign a job, the Pi could return it, and the same identity survived the reboot.
- A short arithmetic question asked in the browser came back answered.
- CPU temperature under the tiny-prompt soak stayed between 58.7°C and 65.3°C, with no throttle flag. About 15.5 GiB of system RAM stayed free, which fits a model that lives on the accelerator.
- The fan, once the current agent was the one reporting it, was spinning.
That is an initial node. It is one machine, on one LAN, with the coordinator on a computer that has to stay awake. If the Mac sleeps, heartbeats fail until it returns, and the agent keeps retrying. Local inference on the Pi does not depend on that Mac. The registry does.
Accelerator temperature and utilisation were not available from this runtime, so they were omitted rather than stored as zero. SMART data for the boot disk was blank. TRIM had not been verified. There is still no recovery card. Output was not verified by anything other than "the node sent text". No contribution was accounted. No training step was run. The long-term question in Part 1, whether learning can scale across unreliable edge devices, was not touched.
A 1.5 billion parameter instruct model, compiled by someone else and loaded as a HEF, is a useful first workload. It is not a KRXY model.
What I would not conclude
The 16 GB board did not prove that 8 GB was too small. This model did not sit in system RAM. The next workload might.
The SATA disk behind a 5 Gbit/s bridge did not prove anything about NVMe. The plan still describes NVMe, because that was the storage I thought I was buying. The disk that booted is the one in the table above.
The 0.7 s median is not a benchmark against any other runtime. A later comparison would need the same prompt, the same token allowance, and a record of what was measured. I did not have that on this day.
Ethernet remains the intended baseline. It was not the path this node used.
Where Part 3 starts
The interesting residue of the day is the agent. A file on disk, a systemd unit, and a process started from a shell had been three different things, and only one of them was talking to the control plane. The node identity survived that. The next entry, when I write it, stays with that agent: what it reports, what it is allowed to claim, and how a worker keeps one name across a restart.
Building KRXY series
Part 1 — The Beginning. What I wanted to build.
Part 2 — The first node. What I actually started building. This entry.
Later parts will follow the work in order. I will link them when they exist.
Comments
Join the discussionNo comments yet. Be the first to comment.
Building KRXY
A development journal for KRXY. Posts follow the work in order: the original plan, the hardware, what gets built, what fails, and what is actually measured.




