Table des matières


Créé le: 2024-09-07 ; Révisé le: 2024-09-07

Développons avec Simon - 8 - Utiliser LocalAI avec Spring AI

Vidéo (48 minutes)

Introduction (00:00)

Cette semaine, j’ai ajouté une fonctionnalité dans mon application d’étude https://foilen.com/fr/logiciels/ : une intégration avec LocalAI en utilisant SpringAI qui va générer des phrases avec le mot de vocabulaire automatiquement. Il arrive à créer des phrases pour environ 90% des mots (dans les autres 10% c’est que des fois il conjugue le verbe au lieu de l’utiliser tel quel ou va écrire “mère” au lieu de “parent”)

Ça va faciliter l’ajout de mots.

Vous pouvez voir le commit complet dans Git sur https://github.com/foilen/foilen-studies/commit/d8c3abced5f41fc29c6298173f9fd5083c98da17 .

Tour du logiciel avec la fonctionnalité à ajouter (00:31)

Lorsque nous sauvegardons une liste de mots, les mots sans phrases entrées par l’utilisateur sont ajoutés à une file.

Générer manuellement avec Bing Copilot (02:45)

En utilisant l’invite suivant:

Écris de courtes phrases avec un mot ci-dessous par phrase écrit avec la même orthographe exactement:
- mot1
- mot2
- mot3

Ce qu’est LocalAI (04:45)

  • https://localai.io
  • Gratuit
  • Installable avec Docker sur nos ordinateurs
  • Expose un API compatible OpenAI avec différents services et modèles
    • Génération de texte
    • Génération d’images
    • Texte à son
    • Son à texte
    • etc.

Ce qu’est SpringAI (06:36)

Aller dans le code et réinitialiser le commit (08:47)

En faisant un git reset --soft {hash} pour revenir à l’état avant l’ajout de la fonctionnalité, mais en gardant les modifications dans l’index de Git.

build.gradle (10:03)

Ajouter le Maven pour Spring:

repositories {
  maven { url 'https://repo.spring.io/milestone' }
}

Ajouter la version (voir la plus récente sur https://repo.spring.io/ui/native/milestone/org/springframework/ai/spring-ai-openai-spring-boot-starter/ ):

ext {
  springAiVersion = "1.0.0-M2"
}

Ajouter la dépendance:

dependencies {
  implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
}

Ajouter le BOM (explication de ce que c’est à 11:24):

dependencyManagement {
    imports {
        mavenBom "org.springframework.ai:spring-ai-bom:$springAiVersion"
    }
}

application.properties (12:45)

spring.ai.openai.base-url: https://localai.myhost.com
spring.ai.openai.api-key: xxxxxxxxxxx
spring.ai.openai.chat.options.model: gpt-4
  • Explication du choix de modèle (13:40)
    • Par défaut, c’est le modèle gpt-4o qui est le plus récent d’OpenAI
    • Pour LocalAI, il faut utiliser gpt-4
      • Ce n’est pas vraiment le modèle GPT-4, mais c’est pour simplifier l’utilisation de l’API.
      • Le vrai modèle utilisé est huggingface: //NousResearch/Hermes-2-Pro-Llama-3-8B-GGUF/Hermes-2-Pro-Llama-3-8B-Q4_K_M.gguf

AiSpringConfig (14:50)

@Configuration
public class AiSpringConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder.build();
    }

}

AiGenerationServiceImpl (15:34)

  • Explication de l’utilisation de ChatClient (16:10)
  • Explication des types d’invites (prompt): système vs utilisateur (16:17)
  • Explication de l’invite système utilisé ci-dessous (17:11)
  • Explication de l’invite utilisateur utilisé ci-dessous (19:47)
  • Explication de l’utilisation de call() (19:56)
public static final String SENTENCE_SYSTEM_PROMPT = """
  - As an elementary school teacher, create a dictation sentence that includes the following word, written as is with the same gender number. When it is a verb, keep it in the infinitive form or in the conjugation form to stay the same.
  - The sentence must be in {LANG}.
  - Only output the sentence.
  """;

@Autowired
private ChatClient chatClient;

@Override
public String generateSentence(Locale locale, String word) {

    logger.info("Generating sentence for word: {} in locale: {}", word, locale.getDisplayLanguage());

    String sentence = chatClient.prompt()
            .system(SENTENCE_SYSTEM_PROMPT.replace("{LANG}", locale.getDisplayLanguage()))
            .user(word)
            .call()
            .content();

    return sentence;
}

Puis c’est tout pour l’utilisation de LocalAI avec SpringAI.

L’intégration dans Foilen Studies (20:57)

La suite de la vidéo est à propos de comment j’ai intégré cette fonctionnalité dans mon application d’étude:

  • Vérification que la phrase est valide (que le mot est bien dedans) (21:17)
    • Les tests unitaires (24:40)
  • Ajouter les mots sans phrases dans une file (26:26)
    • Le cache des mots pour lesquels nous sommes incapables de générer une phrase (29:18)
    • La configuration du cache, de la file et de la serrure dans MongoDB (30:34)
    • Lors de la sauvegarde d’une liste de mots (34:39)
    • Logique pour ajouter les mots sans phrases dans une liste lorsque la file est vide (35:30)
      • La requête dans MongoDB pour trouver les mots sans phrases (36:16)
  • Logique pour traiter les mots qui sont dans la file (38:32)

Future idée d’utilisation de SpringAI avec LocalAI (47:17)

J’aimerais faire un script qui traite mes articles sur mon site et:

  • génère une invite de génération d’image en résumant l’article
  • et génère une image.

Ainsi, je pourrais le laisser tourner pendant la nuit et avoir des images pour mes articles.