Kiji Proxy sur WSL 2 ARM64 : ce que l'absence de binaire officiel oblige à comprendre
Kiji est un privacy proxy open source de Dataiku qui s'intercale devant les appels API vers un LLM pour anonymiser les données sensibles avant qu'elles ne sortent, puis restaurer les valeurs originales dans la réponse.
Sur le papier, l'intégrer à un pipeline tient en une ligne de configuration proxy. Dans les faits, Dataiku publie des releases pour macOS et pour Linux amd64, mais aucun binaire ARM64 Linux, et aucune image Docker officielle. Sur un poste WSL 2 tournant nativement en arm64, ça ferme la voie la plus simple.
La première option, l'émulation QEMU via --platform linux/amd64, fonctionne en quelques minutes. Elle a un coût : l'inférence ONNX du modèle de détection PII (DistilBERT quantifié) passe par l'émulateur, ce qui reste correct en usage ponctuel mais devient pénalisant sur un flux dense. La vraie solution sur WSL 2 ARM, c'est la compilation native, ce qui a demandé de reconstituer la chaîne de build à la main : cloner le dépôt, récupérer libtokenizers (daulet/tokenizers v1.27.0) et ONNX Runtime v1.24.2 en version aarch64, puis compiler le binaire Go avec CGO et les modèles embarqués.
Premier piège : les modèles
Le premier vrai piège n'était pas dans la compilation, mais dans les modèles. Le fichier attendu, model_quantized.onnx, ne correspondait pas au nom réellement présent, model.onnx, et surtout la version quantifiée officielle publiée sur HuggingFace s'est révélée simplement cassée sur ARM64 : tous les tokens classifiés au label 0, avec un score de confiance artificiellement élevé. Un test direct en Python avec onnxruntime a confirmé que seule la version non quantifiée fonctionnait correctement sur cette architecture. La correction a consisté à utiliser model.onnx, renommé en model_quantized.onnx pour respecter le nom attendu par le binaire.
Deuxième piège : GLIBC
Le deuxième piège est classique mais coûteux à diagnostiquer sans méthode : GLIBC_2.39' not found. Le binaire avait été compilé sur WSL 2 Ubuntu 24.x, mais l'image Docker de base était en 22.04, donc en GLIBC 2.35. Rien à voir avec le code, tout à voir avec l'alignement entre l'environnement de build et l'environnement d'exécution. Passer la base image en Ubuntu 24.04 a réglé le problème d'un coup.
Ajustements opérationnels
Restaient des ajustements plus opérationnels. Les ports 8080 et 8081 étaient déjà pris par d'autres services sur la même machine, remappés en 18080 et 18081. Les timeouts HTTP par défaut dans server.go, 15 et 30 secondes, étaient trop courts pour des réponses LLM parfois plus lentes, portés à 60 et 300 secondes. Et le démarrage du conteneur, qui extrait un modèle embarqué de 700 Mo à chaque lancement, prend une trentaine de secondes, ce qui a nécessité d'élargir la fenêtre de health check du script de build automatisé.
La validation finale a porté sur le vrai objectif : masquage effectif des PII en français et en anglais (prénom, email, IBAN, numéro de téléphone, numéro de sécurité sociale), avec restauration automatique des valeurs dans la réponse du LLM via le proxy transparent. Un point mérite d'être noté pour la suite : la détection NER s'est montrée fiable sur du texte en phrase naturelle mais est passée à côté des noms et téléphones dans un format structuré Label: valeur, un angle mort corrigé ensuite par des règles regex déterministes dédiées à ce format.
Rien de tout ça n'est spécifique à Kiji. C'est la mécanique habituelle quand on adopte un outil sans binaire officiel pour son architecture.
La compilation native est rarement le problème, ce sont les hypothèses implicites sur l'environnement cible — la version de GLIBC, le nom exact d'un fichier de modèle — qui font perdre du temps si on ne les traque pas méthodiquement.
Un terrain semé de pièges similaires ?
Build ARM64, privacy proxies, LLM en production — partageons nos retours.
