J'ai commencé à travailler sur une fonctionnalité d'IA pour le travail parce que j'ai vu une opportunité de contourner un ancien outil expert encombrant, et bien sûr, chaque start-up doit être une start-up d'IA . Lors du prototypage de cette fonctionnalité, j'ai rencontré quelques problèmes étrangement familiers. J'ai donc parcouru mes journaux et trouvé Maggie, la petite traductrice que moi et un ami avons construite avant la pandémie. Cela fait presque sept ans, et les mêmes problèmes qui ont affecté les tests d’IA et le déploiement en production sont toujours un fléau absolu, même si l’état de l’art a fait des progrès significatifs. Voici une réflexion sur mes notes, pensées et code de Maggie pour démontrer les problèmes courants sur la voie de la production de l'IA. J'espère que cela vous aidera.
Maggie est le nom de la plus jeune enfant des Simpsons de la série du même nom. Maggie est un bébé qui n'a pas encore appris à parler. L'oncle de Maggie, Herb, touche le fond après une mauvaise décision commerciale et emménage chez les Simpson. Il construit miraculeusement un bébé traducteur fonctionnel après s'être inspiré de sa nièce et de la frustration de la famille face à son manque d'élocution. De la même manière, l'idée de construire un bébé traducteur est venue à mon ami Chris suite à sa relation avec sa petite sœur, qui avait du mal à comprendre la parole. C'est pourquoi nous avons nommé notre application Maggie.
Chris travaillait dans un laboratoire pour bébés à l'époque et il a compris qu'il y avait des limites physiologiques au spectre des sons que les enfants d'un certain âge pouvaient émettre. À partir de cette idée, il a rassemblé des données d’entraînement et construit un modèle de classification des cris de bébé – un exploit impressionnant, car il était étudiant en physique sans aucune expérience en CS.
Nous avons partagé un cours – Engineer Service Learning – où toute la classe a travaillé sur la certification LEED pour l'un des bâtiments du campus. Je me souviens de lui comme du gars insouciant qui montait sur un longboard pour aller en classe. Notre première interaction a eu lieu à l'extérieur de la classe, dans le parking sombre d'une épicerie, où je l'ai vu se préparer à faire du vélo tout-terrain. Il s'était garé à côté de ma voiture et nous avons discuté. Puis j'ai remarqué un papier froissé à côté de lui, je l'ai ramassé, j'ai remarqué que c'était de l'argent et je lui ai dit qu'il avait laissé tomber son argent. Il a dit que ce n'était pas le sien, mais je lui ai dit de le garder. Nous ne savions pas combien cela coûtait ; le parking était trop sombre. 1 $, 10 $ ou 100 $. Je lui ai dit que j'espérais que ce serait 100 $. C'était 10 $. Mais cette première interaction a établi suffisamment de confiance entre nous pour qu'en quelques semaines, alors que nous travaillions tous les deux au Venture Lab – l'incubateur de startups de l'UC Merced – il m'a demandé de créer une application pour déployer son bébé traducteur. Sans le Venture Lab, nous n’aurions jamais pensé à collaborer. Je n’ai certainement pas dit à des camarades de classe au hasard que je construisais des applications Android, et il ne s’est pas non plus vanté de son modèle de traduction pour bébé. Il y a une magie magnétique dans les troisièmes espaces en personne que vous ne devriez pas sous-estimer.
Malgré la construction d’un modèle fonctionnel. Chris ne savait pas comment le déployer. C'était début 2017 et il n'y avait pas beaucoup de cours ou de guides le démontrant. Son mentor chez TensorFlow a recommandé le déploiement sur Android, mais l'apprentissage du développement mobile était un pont trop loin. Je connaissais Android et j'avais déployé plusieurs applications sur le Play Store, mais même pour moi, c'était exagéré. Alors, j’ai fait la chose la plus facile.
J'ai mis le modèle sur un serveur et lui ai fait des appels API. Exécuter le modèle sur un serveur Flask était étonnamment simple : importer TensorFlow, charger le modèle à partir du disque local (je n'ai même pas pensé à déployer le modèle de manière à ce qu'il soit facile de le versionner jusqu'à plus tard) et pointer les requêtes vers il. Mais il y a eu quelques pièges :
Malgré ces problèmes, cela a fonctionné. Le partage de l'analyseur d'entrée du modèle et du code du transformateur a résolu le premier problème. Traiter le modèle comme une boîte noire et s'en moquer a facilité la création de tests d'intégration autour de lui. Ces tests garantiraient qu'il n'y avait pas de désalignement inattendu entre le serveur et le modèle, à condition que les simulations soient exactes. Il existe désormais des interfaces de modèles qui peuvent garantir une exactitude simulée pendant le développement. De nos jours, le déploiement et le contrôle de version des modèles ne constituent pas un problème nécessitant de nouvelles solutions pour la plupart des cas d'utilisation.
En revanche, les problèmes de latence et de disponibilité nous ont finalement poussé à déployer le modèle sur l'application en périphérie. Cela présentait l'avantage de supprimer la latence du réseau, d'utiliser le processeur beaucoup plus rapide du téléphone et de maintenir l'application en arrière-plan, ce qui a résolu notre problème de latence de démarrage et réduit nos coûts d'hébergement. Mais bien sûr, de nouveaux problèmes sont apparus.
Nous avons passé beaucoup de temps à débattre de l'endroit où placer le modèle. Nous recherchions la vitesse et la certitude du téléphone, mais implorions la sécurité et la facilité de déploiement du serveur. Au départ, mettre le modèle sur le serveur était séduisant :
En fin de compte, nous avons décidé de mettre le modèle dans l'application en raison des deux premiers points : l'application n'était pas convaincante si vous deviez attendre qu'elle soit traduite ou si elle était occasionnellement en panne. Quelques secondes de latence semblent une éternité quand on a un nouveau-né qui pleure dans les bras. Mais mettre le modèle au téléphone avait ses problèmes, comme je le décrirai dans la section suivante.
La leçon que j'en ai tirée est que vous devez optimiser pour la meilleure expérience utilisateur, même si la solution n'est pas évolutive, ne vous assure pas de croissance future ou met en danger votre propriété intellectuelle. Les entreprises vivent et meurent selon leur expérience utilisateur, surtout s'il s'agit de nouvelles entreprises qui ont besoin de gagner la confiance et de construire une marque.
La mise en place du modèle sur le téléphone s'est accompagnée d'une montagne de difficultés techniques. Certains d’entre eux n’existent pas aujourd’hui, mais la plupart existent. Nous étions à la pointe. TensorFlow pour Android était à peine sorti : la sortie publique avait eu lieu en février 2017 et je construisais l'application en mars. Mais avec la persévérance et l'aide précieuse de Pete Warden de TensorFlow, nous avons réussi à faire fonctionner le modèle dans l'application.
Le premier problème consistait à obtenir le modèle dans le package APK. À l'époque, Android avait une limite de 50 Mo d'APK et une fonction d'extension qui permettait aux applications d'être plus volumineuses en téléchargeant des composants après l'installation. Cependant, j'ai jugé la fonctionnalité d'extension non sécurisée car elle impliquait d'exposer le modèle sur un serveur. Nous avons donc décidé de quantifier l'application, une technique qui consiste à réduire la précision de toutes les entrées et sorties de chaque couche.
Dans notre cas, nous avons converti tous les nombres à virgule flottante en nombres entiers, ce qui a considérablement réduit la taille du modèle et l'a rendu plus rapide, mais cela a également réduit la précision. Chris a parcouru plusieurs itérations du modèle avec différents schémas de quantification et a finalement opté pour la quantification entière malgré la réduction de la précision. C’était utile tant que le modèle fonctionnait mieux que les nouveaux parents. Bonus : cela a résolu le problème de mise à jour : télécharger des centaines de Mo de données à chaque mise à jour de modèle était une tâche difficile sur les connexions Internet limitées, mais quelques Mo étaient gérables (cela me semble idiot maintenant, car les gens téléchargent régulièrement des Go de contenu vidéo sur leur téléphone aujourd'hui). ).
Puis vint une longue série de problèmes mineurs. Le plus important était que les bibliothèques FFT prises en charge par les différentes versions de Java livrées avec Android ne produisaient pas le même spectrogramme sur lequel le modèle avait été formé. Nous avons formé le modèle à l’aide d’une bibliothèque C++ FFT et il a produit des spectrogrammes de différentes couleurs et dimensions. Étant des outils secrets, les versions C++ et Java étaient écrites de manière opaque et difficiles à modifier. Autre décision rapide : nous avons décidé de recycler le modèle en utilisant les spectrogrammes Java FFT. Cela impliquait de transformer tous les fichiers audio en spectrogrammes, puis d'exécuter le processus de formation, ce qui prenait des jours sur l'ancien Macbook de mon ami. Mais le problème était résolu et je pouvais me concentrer sur autre chose pendant ce temps.
Mais l’application n’arrêtait pas de se bloquer et de planter. Il s’avère que charger l’enregistrement en mémoire puis créer le spectrogramme en mémoire était une mauvaise idée. L'application monopolisait une grande partie des ressources du téléphone. La solution consistait à enregistrer sur disque et à diffuser. La sauvegarde sur disque était facile ; la partie streaming était difficile car, une fois l'audio quitté la mémoire, tout pouvait lui arriver sur le disque. Un autre programme peut le lire et le modifier ; il peut être supprimé, sa sauvegarde peut échouer, etc.… Ces cas extrêmes n'existent généralement pas sur le Web : vous disposez d'un canal isolé avec votre utilisateur mais pas sur les appareils. S'assurer qu'il y avait suffisamment d'espace pour le faire en premier lieu et nettoyer après l'application était un défi inattendu. J’ai découvert plus tard que c’est une hypothèse mal fondée de croire que si le téléphone disposait de suffisamment de mémoire pour installer votre application, il disposait alors de suffisamment de mémoire pour l’exécuter.
Enfin, l’appareil lui-même était un adversaire : les téléphones Android sont dotés d’une grande variété de processeurs, de quantités de mémoire et, surtout, de microphones. Le problème du processeur et de la mémoire pourrait être résolu en réglant la version Android requise à la dernière version et en espérant le meilleur ; le pire des cas était une application lente – il n’existe aucun moyen de définir directement les exigences en ressources dans Android. Le vrai problème était de prendre en compte les différentes qualités des microphones : Android vous permet d'exiger des microphones sur les appareils sur lesquels votre application est installée, mais pas le type de microphone.
Je n'ai pas essayé de résoudre ce problème. J'avais de nombreux téléphones testeurs à l'époque et j'ai remarqué à quel point les prévisions étaient pires sur les téléphones bon marché. J'ai décidé que nous n'avions pas le temps de trouver une solution maintenant : nous essayions de nous lancer le plus tôt possible. Parfois, la meilleure solution à un problème est d’en prendre note et de passer à autre chose. Maintenant, je réalise que ce problème nous a orienté vers le produit final : Homer, un haut-parleur intelligent.
Une fois les difficultés techniques surmontées (ou évitées), nous sommes passés au problème plus difficile de la qualité des prédictions. Puisque le modèle vivait sur l’application, nous étions aveugles à ses performances. Si cela fonctionne mal, la seule façon de le savoir est de commenter sur la page de l'application ou de procéder à des désinstallations ; d'ici là il est trop tard. Par conséquent, il était essentiel de créer un wrapper de journaux, de surveillance, de collecte de données et de commentaires autour du modèle.
Le modèle a pris des spectrogrammes et quelques autres informations pour catégoriser les sons émis par le bébé : affamé, inconfortable, souffrant, somnolent et gazeux, telles étaient les traductions. Il a renvoyé une liste de toutes les catégories possibles, chaque catégorie ayant un pourcentage représentant le degré de confiance du modèle dans cette traduction particulière. Tous les pourcentages totalisent 100 – si la traduction la plus précise avait faim à 90 %, alors les cinq autres catégories auraient des précisions qui totalisent jusqu'à 10 %.
La question à laquelle nous avons été confrontés au début était de savoir s'il fallait afficher toutes les traductions (classées de la plus précise à la moins) ou une seule. J'ai choisi d'en montrer une seule parce que je ne voulais pas confondre les gens avec plus de traductions, et c'était plus simple à construire (la paresse est la pierre angulaire d'Agile). Cependant, nous avons rencontré des problèmes avec notre premier groupe d’utilisateurs.
Lorsque le modèle était certain (au-dessus de 80 %), la suggestion fonctionnait : nous n'avons reçu aucune plainte de la part des parents. Mais ce n’était pas toujours aussi confiant. Lorsque la précision de la traduction était inférieure à 80 %, elle était alors aussi bonne que le parent ou la supposition. Cela va à l’encontre du but de l’application ; il devrait offrir des traductions plus précises que les tentatives paniquées d'un nouveau parent pour apaiser son enfant. Et c’est ce qui s’est produit, sans surprise, les 2e ou 3e traductions étaient parfaites. Nous l'avons découvert grâce à des entretiens en personne : les entretiens en personne sont inévolutifs et prennent du temps, mais extrêmement riches en informations ; si vous pouvez en faire un quotidiennement, faites-le. Le bébé pleurait et l'application affichait la mauvaise traduction avec peu de confiance, mais nous essayions les autres traductions (nous les avons vues dans les journaux) et elles fonctionnaient.
C'était contre-intuitif pour moi parce que je considérais l'application comme un traducteur ; il ne devrait y avoir qu’une seule façon de traduire quelque chose, n’est-ce pas ? Faux. L'application était un outil d'exploration permettant aux nouveaux parents et tuteurs de déterminer ce qu'ils devraient essayer en premier. Dois-je essayer de faire faire un rot à mon bébé ? Est-ce qu'il a faim? À quand remonte la dernière fois qu’il a fait une sieste ? Chaque parent passe en revue cette liste de contrôle lorsque son bébé commence à pleurer. Notre application a accéléré cette exploration ; c'est ainsi que les parents l'ont utilisé, et c'est le retour que nous avons reçu une fois que nous avons déployé plusieurs traductions. Ce n’était pas la fonctionnalité phare, mais elle a certainement transformé l’application d’un gadget en un outil à usage quotidien, un compagnon de confiance lorsque le conjoint est parti ou que les grands-parents dorment.
Forts de ces données, nous avons rapidement décidé d'afficher davantage de traductions. L’astuce consistait à déterminer combien. L'affichage de toutes les traductions (les cinq catégories) donnait l'impression que l'application répétait les mêmes traductions à chaque fois. Que penseriez-vous si Google vous montrait les quatre mêmes restaurants à chaque fois que vous recherchiez de la nourriture ? Nous avons choisi les trois meilleures traductions : cette partie artistique et cette partie données.
Les gens sont enclins au chiffre trois pour une raison quelconque. Les données ont montré que la confiance du modèle dans les autres traductions a chuté de manière significative après la troisième traduction. Si la première traduction avait un niveau de confiance de 70 %, la deuxième aurait 20 %, la troisième 9 % et le reste serait inférieur à 1 %. Nous avons donc abandonné ces traductions. Il y avait une petite chance que ces traductions supprimées soient exactes, mais les inclure risquait de rendre l'application répétitive. Le choix était qu’un utilisateur sur 100 recevrait des traductions entièrement fausses, ou que tous les utilisateurs verraient des traductions inutiles et penseraient que l’application devinait. C'était un choix facile.
Bien sûr, avec le recul, j'aurais dû tester cela en utilisant un bandit multi-bras : publier cinq versions différentes de l'application, une pour chaque choix, par exemple, afficher une traduction, en afficher deux, en afficher trois, etc., et migrer lentement les personnes. sur la version de l’application qui a obtenu les meilleurs résultats. La principale mesure de réussite serait le nombre de personnes ayant cliqué sur la coche verte (satisfaites de la traduction). Mais à un stade aussi précoce, je crois que nous avons pris la bonne décision et, plus important encore, que nous avons pris la décision de la bonne manière. Nous étions ouverts d'esprit, nous ne considérions aucune décision comme concrète (pas d'ego ici), nous prenions constamment contact avec nos utilisateurs et nous les écoutions, même si cela ne nous semblait pas bien.
Chaque interaction est une opportunité de s’améliorer et d’impressionner. Mon inquiétude dès le début de cette aventure était que le modèle avait simplement de la chance, qu'il y aurait un père ou une mère célibataire à qui on dirait que son bébé pleurait parce qu'il avait des gaz et qu'il rotait son bébé à mort. Peu probable, mais nous nous sentions responsables du bien-être du bébé de chaque utilisateur. Nous avons donc retardé le lancement en ajoutant une fonctionnalité de commentaires à l'application.
Après chaque traduction, on vous a demandé à quel point elle était utile : une page incontournable. Ensuite, l'application a téléchargé les commentaires des utilisateurs, la sortie du modèle, le type d'appareil et le spectrogramme. Au départ, j'ai téléchargé le fichier audio mais je me suis vite rendu compte que le microphone captait beaucoup de bruit de fond. Pour la confidentialité de nos utilisateurs, nous choisissons de télécharger uniquement le spectrogramme. Ce que je ne savais pas à l'époque, c'est qu'il était possible d'inverser un spectrogramme et de reconstruire l'audio, bien qu'avec une qualité inférieure et avec quelques difficultés. C'était notre volant d'inertie.
Cependant, je passe sous silence les débats et les multiples ébauches qui ont conduit à cette version finale. Il est difficile de décider quelles données collecter, comment mesurer le succès et comment définir le succès, mais il s’agit d’un processus itératif que vous pouvez suivre par petites étapes et améliorer. Le meilleur conseil que j'ai reçu a été de définir à quoi ressemble le succès ou, si c'est trop difficile, à quoi ressemble l'échec (pour moi, il est beaucoup plus facile de définir l'échec que le succès - je ne sais jamais ce que je veux, mais j'en suis sûr). ce que je veux éviter) et soyez précis. À partir de cette réponse, dérivez les mesures que vous pouvez utiliser pour juger de vos efforts : si l'échec entraîne une perte d'utilisateurs avant que leur bébé ne soit trop vieux pour utiliser l'application, mesurez la durée de vie moyenne de l'application sur le téléphone de l'utilisateur. Mais gardez à l’esprit que ces définitions et mesures ne sont pas statiques : elles changeront. Il vous suffit de décider et de vous y tenir jusqu'à ce qu'ils cessent de fonctionner. Ils cesseront de travailler lorsque vous cesserez d’apprendre d’eux ou du moins lorsqu’il deviendra plus difficile d’apprendre d’eux. C'est le but, apprendre et s'améliorer, le reste n'est que des détails.
À l’ère de l’IA/ML, l’actif numérique le plus précieux d’une entreprise sont les données qui lui sont confiées, et non le modèle. La croissance de ces données – de préférence de manière transparente et éthique – est essentielle à un succès continu. Par conséquent, chaque interaction utilisateur doit être traitée comme un moment de génération de valeur, quels que soient les taux de conversion. Il s’ensuit donc que chaque interaction doit laisser l’utilisateur impressionné et vouloir revenir. Nous avons construit quelque chose qui a époustouflé et inspiré ; nous avons eu une grande designer, Teresa Ibarra , qui a pris mon brouillon brut et l'a peaufiné en une application apaisante et joyeuse à utiliser. Et chaque traduction rendait la suivante meilleure.
La dernière chose que nous avons construite était Homer. Après avoir mené des dizaines d'entretiens en personne avec des utilisateurs de l'application et appelé encore plus de personnes, nous avons réalisé qu'il était difficile et peu pratique de rechercher votre téléphone, de déverrouiller l'écran, de trouver notre application, de l'ouvrir et de cliquer sur traduire tout en tenant votre enfant qui pleure. Pourquoi a-t-il fallu si longtemps pour s’en rendre compte ? Nous étions deux célibataires d'une vingtaine d'années, sans enfants. Je ne me souviens pas de la dernière fois où j'ai tenu un bébé dans mes bras, et encore moins apaisé ses gémissements. Nous avons donc décidé de construire un babyphone utilisant un haut-parleur intelligent. J'ai commandé un kit chez Raspberry Pi et construit un haut-parleur Google Home personnalisé avec un gros bouton bleu sur le dessus.
Chris avait l'idée géniale de vendre le modèle à des fabricants de babyphones, mais nous ne parvenions pas à gagner du terrain auprès de ces sociétés, alors pourquoi ne pas construire notre propre babyphone à l'aide d'un haut-parleur intelligent ? Après avoir construit Google Home, j'ai créé un script bash pour exécuter le traducteur au démarrage. Le traducteur a utilisé le SDK de Google Home pour traduire la phrase déclencheur « D'accord, Google, traduis ». Le traducteur était un script Python qui lisait l'audio des microphones, le transformait en spectrogramme, puis l'envoyait à un serveur pour être traduit. J'ai gardé les choses agiles, et ça a marché ! Nous avons enfin eu notre application phare, mais elle n'a pas sauvé l'entreprise.
Nous avons manqué de financement – les prix en argent que nous avions gagnés lors d’un concours. La vie s’abattait rapidement sur nous deux. Nous avons obtenu notre diplôme universitaire et nous sommes tous deux rentrés chez nous. J'ai accepté un emploi dans la région de la Baie et Chris est parti s'occuper de sa mère malade au Texas. Le démarrage a échoué.
Les startups sont difficiles et déchirantes. Vous ne pouvez pas les faire à temps partiel. Toute personne ayant un intérêt doit travailler à temps plein ou doit partir pour faire de la place à quelqu'un d'autre. Ou alors vous devez réduire vos ambitions, voire les abandonner complètement. Il existe désormais des problèmes qui peuvent être résolus de manière rentable à temps partiel, mais en valent-ils la peine ? Est-ce qu'ils vous excitent ?
Si j'ai appris quelque chose (outre la difficulté de déployer des modèles ML sur Android), c'est que vous devez vraiment vous soucier du problème que vous résolvez. Vous devez trouver le courage de vous y engager à plein temps malgré les risques financiers et le coût d’opportunité énorme. Je n’avais aucune chance d’abandonner mon travail en technologie pour travailler là-dessus. J'ai adoré aider les nouveaux parents et les papas désespérés ; la technologie était exaltante à apprendre et à construire, mais comment pourrais-je expliquer à mon père pourquoi je retournais dans notre appartement exigu de la section 8 après avoir obtenu mon diplôme ? Comment pourrais-je refuser un salaire à six chiffres après avoir vécu si longtemps grâce à l’aide sociale ?
Qu’en est-il du capital-risque ? Pourquoi n'avez-vous pas essayé de récolter des fonds ? La réalité est que les investisseurs en capital-risque ne répondent au téléphone que s’ils vous connaissent, connaissent l’école que vous avez fréquentée ou l’entreprise dans laquelle vous avez travaillé. Ils ne se soucient pas de ce que vous avez construit – à moins que cela ne soit rentable, votre innovation n'est qu'un détail mineur – les sociétés de capital-risque investissent d'abord dans les fondateurs et les équipes et dans les produits en dernier. Mais la plupart d'entre eux ne savent pas comment sélectionner de bons fondateurs ou de bonnes équipes, alors ils laissent les responsables des admissions des écoles d'élite ou des FAANG le faire.