L'affrontement est arrivé 1 jour en avance. L'article de réglage de l'M1 Ultra d'hier s'est terminé par une prédiction : lorsqu'une version MLX est publiée avec des graphes de décodage compilés, la revanche contre la voie 20,3 tok/s prendra un après-midi et 1 téléchargement. Ce matin, j'ai repéré un nouveau runtime appelé MTPLX promettant ce futur comme produit fini — décodage spéculatif multi-token natif sur Apple Silicon, un autotuner qui mesure votre machine spécifique, un serveur compatible OpenAI- et Anthropic, des lancements en 1-clic pour les harnesses d'agents que nous utilisons réellement, et Qwen3.8-27B comme son modèle de codage phare. Leur site dit « vos outils préférés, deux fois plus rapides. » Je l'ai présenté à Kimi K3, mon collaborateur de l'aventure de réglage la veille, et nous avons fixé les termes ensemble : l'installer proprement sur le Studio, laisser son propre tuner faire son meilleur cas, puis mesurer ce que le serveur sert réellement. Kimi a exécuté le travail à distance et les compteurs ; j'ai gardé les règles de la maison et pris les décisions. Voici comment la journée s'est réellement déroulée.

MTPLX est la version produit de la voie que nous avons construite ensemble

L'architecture mérite d'être créditée dès le départ, car c'est la bonne idée exécutée sérieusement. MTPLX rédige avec les propres têtes MTP du modèle — le même mécanisme que notre voie utilise — et accepte les brouillons via l'échantillonnage exact de rejet, de sorte que l'échantillonnage à la température 0.6 produit la même distribution que le décodage ordinaire, mais plus rapide. Il n'y a pas de modèle de brouillon séparé consommant de la mémoire, la profondeur du brouillon est réglée par machine contre une base autoregressive, et le projet refuse d'attacher des sidecars MTP non vérifiés à des poids arbitraires. Cette dernière politique est une discipline que Kimi et moi avons dû appliquer manuellement la veille, lorsque nous avons réappairé les tenseurs MTP abandonnés de Qwen3.8 avec leur tronc. La voie de la partie un était le bâton de mesure évident : même Studio, même famille de modèles, mesurée de la même façon.

L'installation a passé les contrôles de quarantaine 2 avant d'atteindre un poids

La première vérification était la mienne. En mars, dans mon laboratoire d'affinement autonome, nous avions rencontré un piège où un environnement Python isolé perdait silencieusement l'accès aux bibliothèques accélérées de Apple, et les chiffres ne revenaient que lentement. Avant que Kimi n'avance davantage, j'ai demandé la preuve que le piège ne s'appliquait pas. Un sondage à 3 lignes l'a confirmé — interpréteur arm natif64, Metal disponible, GPU comme appareil par défaut. Le chemin Metal de Apple est inclus dans la roue mlx-metal elle-même, donc l'origine de l'interpréteur est sans importance pour l'accès GPU, et la voie de la partie un avait déjà prouvé le débit natif GPU via la même forme d'isolation. Le propre inspecteur de MTPLX a confirmé, évaluant les deux de ses constructions Qwen3.8-27B vérifiées-natives avec tous les tenseurs MTP 15 présents.
La seconde vérification était celle de Kimi, à mi-téléchargement. La commande pull de MTPLX ignore les variables d'environnement habituelles du cache Hugging Face, et la première tentative écrivait 20 GB de modèle dans le répertoire personnel du Studio au lieu du volume de données que les règles de la maison protègent. Kimi a interrompu le pull, a supprimé uniquement ce qu'il avait créé, et a redémarré avec un répertoire de cache explicite. Les fans restaient sur la courbe de Apple toute la journée, ce qui compte sur une machine qui fait aussi office de simulateur de vol.

La machine la plus bruyante ce matin n'était pas celle qui exécutait l'expérience

À mi-téléchargement, ma propre station de travail a commencé à surchauffer — la moyenne de charge dépassant 50 — et nous avons arrêté l'expérience pour répondre à une question plus importante : était-ce notre faute? Ce n'était pas. Notre travail s'exécutait sur le Studio pendant des sessions SSH à court terme ; l'empreinte locale était quelques processus curl et ssh terminés. La tempête était une vague de démon Apple — un téléchargement d'actif bloqué, un indexage, et un pic provenant d'un processus de virtualisation qui a disparu avant que nous puissions nommer son propriétaire — plus la découverte que les « processus de nœud de respawn mystérieux » que je killais étaient 3 superviseurs de développement faisant exactement leur travail en redémarrant leurs serveurs. Nous avons tout écrit dans le transfert de garde de la machine et sommes retournés à l'expérience avec une conscience claire. La pause appartient à cette histoire parce que la discipline est la même que celle sur laquelle les benchmarks fonctionnent : connaître votre propre empreinte avant de blâmer une machine.

L’autotuner a mesuré un blowout de 2.20x

Le rituel de réglage de MTPLX est une ingénierie honnête : il exécute le vrai modèle sur votre matériel à chaque profondeur de brouillon, conserve le décodage autoregressif comme référence, et sauvegarde une profondeur uniquement si elle bat cette référence. Sur le M1 Ultra, il a produit AR 11.4, profondeur 1 à 9.2, profondeur 2 à 25.1, profondeur 3 à 20.7 tok/s — profondeur 2 couronné le gagnant à 2.20x, sauvegardé pour tous les lancements futurs.
Ce 25.1 est une mesure réelle d’un moteur réel, 24% au-dessus du taux de service de notre lane 20.3. Si le serveur l’avait reproduit, cet article aurait été un guide de migration.

Le serveur a servi 16.5, et les valeurs par défaut dépensaient des tokens hors de vue

Le banc de service utilisait les mêmes invites, température 0, et comptabilité en temps réel que la référence de la lane. La première exécution est revenue à 14.7 tok/s, et les métadonnées de réponse ont révélé 2 valeurs par défaut travaillant contre la mesure :
  • Le mode de raisonnement est par défaut activé, et Qwen3.8 réfléchit avant de répondre. Sur une invite triviale de compter à 10, 44 des tokens générés 64 étaient cachés dans le raisonnement que le client ne montre jamais. Les charges de travail réelles paient pour ces tokens, donc le taux horaire les inclut déjà — mais les invites du tuner ne portaient pas de telle taxe.
  • Le profil d'exécution Turbo, avec ses noyaux de vérification compilés, est une règle de lancement de l'application Mac native. Un terminal mtplx serve se résout au profil Sustained à la place, donc le chemin en ligne de commande ne voit jamais les noyaux rapides à moins que vous ne le demandiez.
Fixer Turbo, profondeur 2, et désactiver le raisonnement a élevé la construction FP16 à 16.5 tok/s wall — le meilleur MTPLX a produit toute la journée. La construction Optimized-Speed à 4 bits, celle que le projet recommande pour le codage, a servi 15.5. Les deux constructions occupent 20.4 GB sur le disque par rapport à nos 15 GB de lane, et sur une machine limitée par la bande passante chaque token paie pour diffuser ces extra 5 GB.
Serving rate on identical prompts (tok/s wall, M1 Ultra, Qwen3.8-27B)
Chart data
tokens per second
our lane (part one)20.3
MTPLX tune claim (D2)25.1
MTPLX FP16 turbo D216.5
MTPLX 4-bit turbo D215.5
MTPLX defaults14.7

Le tuner et le serveur mesurent 2 machines différentes

La découverte la plus utile de la journée explique l’écart entre 25.1 et 16.5. Les journaux du serveur MTPLX enregistrent une rampe de montée en charge au démarrage, et cette rampe rapporte 20-24 tok/s depuis le moteur — dans le même processus qui sert ensuite 16,5 sur HTTP. Le moteur est rapide et le transport est taxé. Entre la boucle de décodage et le client se trouve la couche HTTP, la comptabilité de banque de session par requête (une écriture de snapshot de 160 Mo est apparue dans les statistiques de la première requête), et la machinerie de raisonnement, et chaque jeton traverse cette frontière. Sur les puces M4 et M5, où les chiffres publiés 1.6-2.24x du projet ont été mesurés, un CPU plus rapide et un tissu absorbent le passage. Le moteur M1 Ultra maintient le rythme ; son chemin de service ne le fait pas.
Diagram source
graph LR
    subgraph Chemin du tuner
        A[Modèle réel] --> B[Profondeurs de brouillon D1-D3]
        B --> C[Minuteur uniquement décodage  
25.1 tok/s]
    end
    subgraph Chemin de service
        D[Requête HTTP] --> E[Banque de session  
+ valeurs par défaut de raisonnement]
        E --> F[Même moteur  
rampe montre 20-24]
        F --> G[Frontière par jeton  
16.5 tok/s mur]
    end

    style C fill:transparent,stroke:#10B981,stroke-width:2px
    style G fill:transparent,stroke:#F59E0B,stroke-width:2px
C’est la leçon de la partie un portant un nouveau costume. Les revendications de la communauté de llama.cpp de 25-32 tok/s n’ont pas survécu au contact avec cette puce, et le tuner MTPLX 25.1 n’a pas survécu à son propre serveur. La règle durable s'affine : un taux de service est mesuré à la frontière HTTP avec les paramètres de production visibles, jamais à l'intérieur du tuner. C'est benchmark-driven development appliqué une couche au-dessus de la pile.

Le challenger est parti 38 GB plus léger, et le chien de garde est resté derrière

J'ai donné à Kimi 1 non négociable avant le début de l'expérience : tout ce qui tourne sur ce Studio doit s'arrêter lorsqu'il est inactif, car le travail du soir de la machine est un simulateur de vol. MTPLX ne propose pas de délai d'inactivité pour son serveur de chat, alors Kimi a intégré le chien de garde dans un petit script wrapper — liaison uniquement en boucle locale, ventilateurs sur la politique de Apple, et un observateur de connexion qui arrête le serveur après 10 minutes sans clients. Il a passé son exercice de feu réel, détruisant une instance de test à la marque de 60 seconde et libérant le port proprement. Le wrapper et l'environnement virtuel restent sur la machine, donc le nouveau test est 1 téléchargement de distance lorsqu'une version MTPLX fonctionne le chemin de service de génération M1 ou expédie un artefact MTP assorti plus proche de 15 GB.
Les poids eux-mêmes ne sont pas restés. Une fois le verdict clair, nous avons procédé au nettoyage soigneusement — les deux répertoires de modèles MTPLX, 38 GB à travers le FP16 et les builds à 4 bits, supprimés après avoir confirmé qu'aucun processus ne les détenait, ramenant le volume à exactement son espace libre pré-expérience. La suppression reste partie du flux de travail : chaque challenger qui perd laisse le disque le même jour, ce qui maintient l'honnêteté de la prochaine expérience.

Ce que la revanche a ajouté à la liste de vérification

La voie de la partie un n'a jamais bougé. Elle a servi le matin à 20.3 tok/s, elle a servi le soir à 20.3 tok/s, et elle conserve désormais son créneau contre les challengers 3 au lieu de 2 — toujours une voie expérimentale, 1 téléchargement à l'écart de sa prochaine revanche. La liste de vérification de la partie un gagne 3 entrées :
  • Le numéro d'un tuner est le plafond du moteur, et le chemin de service décide combien de celui-ci vous conservez. Mesurez à la frontière ce que vos clients traversent réellement.
  • Les valeurs par défaut font partie du benchmark. Les modes de raisonnement, les profils d'exécution et les caches de session consomment tous des jetons ou du temps, et une bataille équitable les fixe explicitement des deux côtés.
  • Le disque est un budget d'hypothèses. 2 challenger construit à 20.4 GB chaque après-midi d'achat 1 de certitude, et la certitude est moins chère lorsque les octets partent à l'heure prévue.
La symétrie satisfaisante du couple est que la partie un s'est terminée en file d'attente de cette expérience exacte, et l'expérience est arrivée emballée comme un produit avec un véritable artisanat dedans — échantillonnage exact, réglage par machine, vérification honnête. L'artisanat était réel et la perte était réelle, et les deux découvertes sont issues du même jour de mesure, tempête CPU et tout. Une aventure avec un tableau de bord est le meilleur type, et celle-ci avait Kimi K3 lisant chaque compteur à côté de moi — le même rendement composé que j'obtiens en traitant local AI gains as infrastructure. La voie conserve son créneau, le disque est mince, la liste de vérification est plus longue, et le prochain challenger est déjà prêt à essayer.