Sloucher-boy

The storyL'histoire

Teaching an idle chip to watch my posture.Apprendre à une puce oisive à surveiller ma posture.

My laptop has an AI chip that almost nothing uses. It took a few days, eight surprises and one ONNX Runtime setting to make it do something useful all day.Mon portable a une puce d'IA que presque rien n'utilise. Il a fallu quelques jours, huit surprises et un seul réglage d'ONNX Runtime pour qu'elle serve à quelque chose toute la journée.

Recent AMD, Intel and Snapdragon laptops all ship with an NPU, a neural processing unit built to run small AI models efficiently. Mine is an AMD Ryzen with a Phoenix / Hawk Point NPU, and for months it mostly blurred my background on video calls. Meanwhile, nearly every webcam AI project on GitHub runs on the CPU. I wanted to know why, so I built something that runs all day: a posture coach.

Les portables récents d'AMD, d'Intel et de Snapdragon ont tous un NPU, un processeur neuronal conçu pour faire rouler de petits modèles d'IA efficacement. Le mien est un AMD Ryzen avec un NPU Phoenix / Hawk Point, et pendant des mois, il a surtout flouté mon arrière-plan pendant les appels vidéo. Pendant ce temps, presque tous les projets d'IA pour webcam sur GitHub roulent sur le CPU. Je voulais savoir pourquoi, alors j'ai construit quelque chose qui roule toute la journée : un coach de posture.

1The newest SDK quietly ran on the CPULe SDK le plus récent roulait en douce sur le CPU

I installed AMD's newest Ryzen AI Software, 1.8. The test printed "Test Finished". Task Manager showed the NPU at 0% the whole time. That release ships no binary for my chip, so it fell back to the CPU and said nothing. Version 1.6.1 works.

J'ai installé la version la plus récente de Ryzen AI Software d'AMD, la 1.8. Le test a affiché « Test Finished ». Le Gestionnaire des tâches montrait le NPU à 0 % tout du long. Cette version ne contient aucun binaire pour ma puce : elle s'est rabattue sur le CPU sans rien dire. La version 1.6.1 fonctionne.

Failed to open xclbin · "Test Finished" · NPU 0%

Only trust the log line that says the model is actually on the NPU.

Ne croyez que la ligne du journal qui dit que le modèle est vraiment sur le NPU.

2The NPU is shared with WindowsLe NPU est partagé avec Windows

The NPU has 5 columns, and Windows Studio Effects (background blur, eye contact) can hold some of them. Some days my model wouldn't load. Other days the camera turned into a black stream at one frame a second. A smaller binary that needs only 1 column is the way out during video calls.

Le NPU a 5 colonnes, et les effets Windows Studio (flou d'arrière-plan, contact visuel) peuvent en occuper. Certains jours, mon modèle refusait de se charger. D'autres jours, la caméra devenait un flux noir à une image par seconde. Un binaire plus petit, qui n'a besoin que d'une colonne, est la solution pendant les appels vidéo.

Failed to create context virtual (0xc01e0009)

3A fast model that couldn't see meUn modèle rapide qui ne me voyait pas

AMD publishes MoveNet ready for the NPU, and it ran in 3.5 ms. But it learned from full-body photos. At a desk, with only my face and shoulders in view, it drew a tiny skeleton on my face and put my "shoulders" at eye level. Fast, and wrong.

AMD publie MoveNet prêt pour le NPU, et il roulait en 3,5 ms. Mais il a appris sur des photos du corps entier. Au bureau, avec seulement mon visage et mes épaules dans l'image, il dessinait un minuscule squelette sur mon visage et plaçait mes « épaules » à la hauteur des yeux. Rapide, et faux.

shoulders ~35 px apart (really ~350 px)

4Test on what the app will really seeTester sur ce que l'appli verra vraiment

So I recorded nine short clips of myself at the desk: upright, slouching, leaning in, head down, in dim light, with and without glasses. Then I wrote a check that fails when the shoulders are in the wrong place, not just missing. MoveNet passed in at most 0.1% of frames.

J'ai donc enregistré neuf courtes vidéos de moi au bureau : droit, avachi, penché vers l'avant, tête baissée, en faible lumière, avec et sans lunettes. Puis j'ai écrit une vérification qui échoue quand les épaules sont au mauvais endroit, pas seulement absentes. MoveNet a réussi dans au plus 0,1 % des images.

"Found" isn't "right". Measure whether the answer is right.

« Trouvé » ne veut pas dire « juste ». Mesurez si la réponse est juste.

5A newer model the NPU can't runUn modèle plus récent que le NPU ne peut pas faire rouler

YOLO11n-pose compiled for the NPU without complaint, then froze on its first frame. Its attention layer is something this generation of NPU can't run. Plain convolutional models are the safe choice here.

YOLO11n-pose a compilé pour le NPU sans broncher, puis a gelé dès la première image. Sa couche d'attention est quelque chose que cette génération de NPU ne peut pas exécuter. Les modèles purement convolutifs sont le choix sûr ici.

DPU timeout … /model.10/m/m.0/attn/Softmax

6The one that workedCelui qui a marché

YOLOv8n-pose, quantized to INT8 with AMD Quark using frames from my own clips, with its final step kept in floating point. It put my shoulders in the right place in every frame of every front-facing clip, in 12 ms on the NPU. 96.5% of its operations run there.

YOLOv8n-pose, quantifié en INT8 avec AMD Quark à partir d'images de mes propres vidéos, avec sa dernière étape gardée en virgule flottante. Il a placé mes épaules au bon endroit dans chaque image de chaque vidéo de face, en 12 ms sur le NPU. 96,5 % de ses opérations y roulent.

7"On the NPU", and burning 7 CPU cores« Sur le NPU », et 7 cœurs du CPU en feu

The model was on the NPU, yet the app used 44% of my CPU. ONNX Runtime's thread pool spins while it waits, by default. Turning that off brought it to 3%. Posture doesn't change 30 times a second, so the finished app looks twice a second and uses 1%.

Le modèle était sur le NPU, et pourtant l'appli utilisait 44 % de mon CPU. Par défaut, le bassin de fils d'ONNX Runtime tourne à vide pendant qu'il attend. Désactiver ça l'a ramené à 3 %. La posture ne change pas 30 fois par seconde : l'appli finale regarde deux fois par seconde et utilise 1 %.

session.intra_op.allow_spinning = 0

"Runs on the NPU" doesn't mean "light on the CPU". Measure the whole app.

« Roule sur le NPU » ne veut pas dire « léger pour le CPU ». Mesurez toute l'appli.

8A calm appUne appli calme

Two ratios of my face and shoulders, compared with my own upright posture, catch slouching, leaning in and looking down. A 30-second rule ignores a brief stretch. The app lives in the tray: the screen edges glow when it matters, a chime plays at most once a minute, and once an hour it sends me for a walk and checks that the chair is empty.

Deux proportions de mon visage et de mes épaules, comparées à ma propre posture droite, détectent l'avachissement, le penchement et le regard baissé. Une règle de 30 secondes ignore un bref étirement. L'appli vit dans la barre des tâches : les bords de l'écran s'illuminent quand ça compte, un carillon sonne au plus une fois par minute, et une fois l'heure, elle m'envoie marcher et vérifie que la chaise est vide.

Every one of these surprises is a reason developers don't build for the NPU yet. None of them is hard once you know it. That's why I wrote them down.

Chacune de ces surprises explique pourquoi les développeurs ne ciblent pas encore le NPU. Aucune n'est difficile une fois qu'on la connaît. C'est pour ça que je les ai notées.

The numbers and the developer checklistLes chiffres et la liste pour développeurs Back to Sloucher-boyRetour à Sloucher-boy