{"id":15131481,"url":"https://github.com/ibjunior/spring-ai-fine-tuning","last_synced_at":"2026-01-20T14:07:59.214Z","repository":{"id":257028810,"uuid":"848762775","full_name":"IBJunior/spring-ai-fine-tuning","owner":"IBJunior","description":"Ce repos contient le code qui permet de générer les données synthétiques pour le fine-tuning avec OpenAI en utilisant Java et Spring AI.","archived":false,"fork":false,"pushed_at":"2024-09-03T10:26:13.000Z","size":219,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-05T21:12:05.134Z","etag":null,"topics":["generative-ai","openai","spring","spring-ai","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IBJunior.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-28T11:11:41.000Z","updated_at":"2024-09-13T21:14:51.000Z","dependencies_parsed_at":"2024-09-14T12:31:58.747Z","dependency_job_id":"bc85ac6c-7cd2-4653-8e09-4674fdda8dfc","html_url":"https://github.com/IBJunior/spring-ai-fine-tuning","commit_stats":null,"previous_names":["ibjunior/spring-ai-fine-tuning"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IBJunior%2Fspring-ai-fine-tuning","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IBJunior%2Fspring-ai-fine-tuning/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IBJunior%2Fspring-ai-fine-tuning/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IBJunior%2Fspring-ai-fine-tuning/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IBJunior","download_url":"https://codeload.github.com/IBJunior/spring-ai-fine-tuning/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399886,"owners_count":20932880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["generative-ai","openai","spring","spring-ai","spring-boot"],"created_at":"2024-09-26T03:42:13.480Z","updated_at":"2026-01-20T14:07:59.207Z","avatar_url":"https://github.com/IBJunior.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring AI : Génération des données synthétiques avec OpenAI pour le fine-tuning\n\nCe repos contient le code qui permet de générer les données synthétiques pour\nle [fine-tuning avec OpenAI](https://platform.openai.com/docs/guides/fine-tuning) en utilisant Java et Spring AI.\n\nLes données générées finales seront en fichier [jsonl](https://jsonlines.org/) ressemblant à :\n````json lines\n{\"messages\":[{\"role\":\"system\",\"content\":\"Tu es un assistant qui fournit des informations concises et précises sur\\nla compagnie aérienne Fly Intelligent en fonction des requêtes des utilisateurs\\n\"},{\"role\":\"user\",\"content\":\"Quelle est la vision de Fly Intelligent pour l'avenir de l'aviation ?\"},{\"role\":\"assistant\",\"content\":\"La vision de Fly Intelligent est de redéfinir l'avenir de l'aviation en intégrant des pratiques durables à tous les niveaux de ses opérations.\"}]}\n{\"messages\":[{\"role\":\"system\",\"content\":\"Tu es un assistant qui fournit des informations concises et précises sur\\nla compagnie aérienne Fly Intelligent en fonction des requêtes des utilisateurs\\n\"},{\"role\":\"user\",\"content\":\"Pourquoi les voyageurs devraient-ils choisir Fly Intelligent ?\"},{\"role\":\"assistant\",\"content\":\"En choisissant Fly Intelligent, les voyageurs peuvent profiter d'une expérience de vol confortable et moderne tout en contribuant à un monde plus durable.\"}]}\n````\n\n## Données de départ\n\nAu départ, on part d'un ensemble de documents PDF (`src/main/resources/documents`) et ensuite pour chaque page du\ndocument PDF, on demande au modèle de\nnous générer un nombre de couples (question, réponse) sous le format `jsonl` ci-dessus\nconfère `src/main/resources/fine-tuning-prompt-template.st` pour voir les détails du prompt.\n\n## Dépendances\n\n* OpenAI (une clé API est nécessaire)\n\n````xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.ai\u003c/groupId\u003e\n    \u003cartifactId\u003espring-ai-openai-spring-boot-starter\u003c/artifactId\u003e\n\u003c/dependency\u003e\n````\n\n* PDF Document Reader pour extraire les contenus des documents PDF\n\n````xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.ai\u003c/groupId\u003e\n    \u003cartifactId\u003espring-ai-pdf-document-reader\u003c/artifactId\u003e\n\u003c/dependency\u003e\n````\n\n* Gson pour convertir les objets java en json\n\n````xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.google.code.gson\u003c/groupId\u003e\n    \u003cartifactId\u003egson\u003c/artifactId\u003e\n    \u003cversion\u003e2.11.0\u003c/version\u003e\n\u003c/dependency\u003e\n````\n\n* Et cette dépendance que j'ai trouvée qui permet de calculer le nombre de tokens d'un prompt. Avant d'envoyer le prompt\n  au\n  modèle, on doit se rassurer de ne pas dépasser le nombre maximal token.\n\n````xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.knuddels\u003c/groupId\u003e\n    \u003cartifactId\u003ejtokkit\u003c/artifactId\u003e\n    \u003cversion\u003e1.1.0\u003c/version\u003e\n\u003c/dependency\u003e\n````\n\n## Structure du projet\n\n### Conversation\n\nLa Classe Conversation représente une conversation une ligne du jsonl final, avec le message utilisateur, système et\nassistant.\n\n````java\npublic class Conversation {\n    private List\u003cMessage\u003e messages;\n\n    //Getters and Setters\n    //...\n    public static class Message {\n        private String role;\n        private String content;\n        //Getters and Setters\n    }\n}\n````\n\n### FineTuningDataService\n\nCe service permet d'appeler le modèle pour chaque page de document pour générer les questions à utiliser pour faire le\nfine-tuning.\n\n````java\n\n@Service\npublic class FineTuningDataService {\n    //code\n    public List\u003cConversation\u003e getConversations() throws InterruptedException {\n        //Code...\n        PromptTemplate promptTemplate = new PromptTemplate(promptResource);\n\n        for (Document document : documents) {\n\n            Prompt prompt = promptTemplate.create(\n                    Map.of(\"numberOfConversation\", \"6\",\n                            \"textPassage\", document.getContent())\n            );\n            //code...\n            String content = this.chatClient\n                    .prompt(prompt)\n                    .call()\n                    .content();\n            //code...        \n        }\n        return allConversations;\n    }\n    //code\n}\n````\n\n### FineTuningDataCreator\n\nAppelle `FineTuningDataService`, ensuite enregistre les données dans le fichier `jsonl`\n\n````java\n\n@Service\npublic class FineTuningDataCreator {\n    //code...\n    public void run() throws InterruptedException {\n        log.info(\"Creating synthetic data started...\");\n\n        List\u003cConversation\u003e conversations = fineTuningDataService.getConversations();\n        Gson gson = new GsonBuilder().disableHtmlEscaping().create();\n\n        for (Conversation conversation : conversations) {\n            String json = gson.toJson(conversation);\n            writeToJsonFile(json.getBytes(StandardCharsets.UTF_8));\n        }\n\n        log.info(\"Created {} conversations\", conversations.size());\n        log.info(\"Creating synthetic data ended...\");\n    }\n    //code...\n\n}\n\n````\n\n## Fine-Tuning sur OpenAI\n\nPour faire le fine-tuning sur OpenAI, on a deux choix, soit le faire par code ou en utilisant le dashboard web.\nPour cet exemple, j'ai utilisé le dashboard.\n\n### Choix du modèle et upload du fichier jsonl\n\nPour cet exemple, ça sera le fichier `src/main/resources/jsons/fly-intelligent-fine-tuning-data.jsonl` et le modèle sera\ngpt-4o-mini.\nEn fait, vous pouvez choisir n'importe quel modèle. Il faut juste qu'il soit différent du modèle utilisé pour la génération\ndes données. Sinon la performance risque de ne pas être au rendez-vous.\n![fine-tuning-1.PNG](src/main/resources/images/fine-tuning-1.PNG)\n\n### Test du modèle sur le playground\n\nAprès l'upload et le choix du modèle, suivez les instructions jusqu'au lancement du fine-tuning. Une fois que c'est\nterminé, vous recevrez une notification.\nVous pouvez alors tester le nouveau modèle sur le playground. Comme suit :\n![fine-tuning-2.PNG](src/main/resources/images/fine-tuning-2.PNG)\n\n## Contact\n\nSi vous avez des questions spécifiques, n'hésitez pas à me contacter\nsur [LinkedIn](https://www.linkedin.com/in/ali-ibrahim-junior/).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibjunior%2Fspring-ai-fine-tuning","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fibjunior%2Fspring-ai-fine-tuning","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibjunior%2Fspring-ai-fine-tuning/lists"}