C’est LE sujet du moment. Entre polémiques, étonnement, questionnement, vous avez tous entendu parler de GPT (Generative Pre-trained Transformer). Que ce soit via DALL-E (mélange entre Dali et Wall-E, un générateur d’image) ou Chat-GPT (un générateur de contenu textuel) vous avez sans doute déjà même vu du contenu généré par GPT. Avec plus de 175 milliards de paramètres, il s’agit du plus gros modèle de langage jamais entraîné. Il sait parler plusieurs langues, connaît aussi bien le développement, les oeuvres de la pop culture que les principes de la physique quantique.

Une des grandes polémiques récente est venu des artistes mécontents de cet art généré par des intelligences artificielles. Notamment MidJourney dont l’art a déjà été utilisé sur des livres vendus dans le commerce.

Mais ici c’est un blog tech. Nous n’allons pas donner notre avis sur le sujet mais nous poser la question: peut-on tenter d’illustrer un livre via une intelligence artificielle ? Nous allons essayer !

Comment procéder

Déjà, comment on illustre un livre ? Je n’en sais fichtre rien. Nous allons donc imaginer le procédé suivant:

  • L’artiste lit le passage à illustrer et s’en imprègne
  • Il se fait un résumé du passage en question pour extraire ce qui doit s’en dégager
  • Il fait une illustration depuis ce résumé

Bon, ce procédé est certes surtout structuré ainsi afin de servir au tutoriel qui va suivre. Mais admettons que ça reste plausible.

Nous allons donc essayer de dégager le même process depuis une IA:

  • D’abord demander à générer un résumé d’un passage d’un livre en une phrase
  • Ensuite générer une illustration dans ce style

Et ça tombe bien ! Avec la sortie en beta de la génération d’image chez GPT, on a désormais tout ce qu’il faut. Et GPT bénéficie d’un essai gratuit, vous avez droit à 18$ de crédit. Ça vous laisse environ le loisir de lancer 1500 fois le projet une fois fini, de quoi illustrer quelques livres !

Parlons peu, parlons code

Déjà créons notre projet:

mkdir BookIllustrator
cd BookIllustrator
npm init

Et je vous laisse remplir en fonction de vos préférences.

Je vous laisse ensuite installer ces trois packages: dotenv, express et openai.
Le dotenv nous servira à stocker la clé de façon propre, express à faire une route qu’on puisse appeler avec des paramètres et openai sert à appeler GPT.

Notre fichier app.js (ou index.js si vous préferez) commencera donc ainsi:

const express = require('express');
const { Configuration, OpenAIApi } = require("openai");
require('dotenv').config();

Et nous allons simplement configurer OpenAI:

const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

Notez que notre clé est égale à « process.env.OPENAI_API_KEY« , créez donc une clé sur https://platform.openai.com/account/api-keys, et ajoutez là sous le nom OPENAI_API_KEY dans un fichier .env créé à la racine de votre projet.

Et nous allons également configurer express de façon très simple:

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.post('/', async (req, res) => {
  // Le code ira ici
});

const port = 3000;

app.listen(port, () => {
  console.log(`App listening on port ${port}`)
});

La base est lancée (je met simplement en async afin d’éviter les then à répétition). Passons désormais au coeur du projet !

Communiquer avec GPT

OpenAi dispose d’une fonction appelée « createCompletion ». Cette fonction permet grossièrement d’appeler la même fonction que ce que vous avez pu voir sur ChatGPT. Pour obtenir un résumé simple nous allons utiliser un promt des plus simples: « Résume-moi ça comme si j’étais un étudiant ». Nous allons donc l’appeler comme ceci:

const response = await openai.createCompletion({
    model: 'text-davinci-003',
    prompt: `Summarize this for a second-grade student in one sentence: ${req.body.prompt}`,
    temperature: 0.7,
    max_tokens: 64,
    top_p: 1.0,
    frequency_penalty: 0.0,
    presence_penalty: 0.0,
});

Bon… Je ne m’embête pas avec les vérifications de si req.body.prompt dans le cadre de l’article, mais libre à vous de le faire. Pour plus de renseignements sur les paramètres entrés vous pouvez regarder ici, mais dans les grandes lignes:

  • model: le modèle d’entraînement utilisé
  • prompt: votre prompt
  • max_tokens: la quantité de tokens max à utiliser (pour éviter de perdre tous vos tokens d’un coup, que vous soyez en version d’essai ou payante)

On va se contenter du minimum niveau vérifs, juste de quoi ne pas faire planter le call:

if (response.statusText != "OK") return;
  
let summary = "";
if (response.data.choices.length > 0) {
    summary = response.data.choices[0].text;
}

De cette façon, ici nous avons la réponse de GPT dans notre variable summary. C’est cette même variable que nous enverrons en prompt à OpenAI pour générer notre image.

Générons l’image

Nous pouvons désormais appeler la fonction createImage:

const img_res = await openai.createImage({
    prompt: summary,
    n: 1,
    size: '512x512',
});

Ici le prompt est évident, la size aussi (je présume ?), et le n correspond à la quantité d’images à générer. Je met juste en 512×512 pour éviter que ça ne prenne trop de tokens (pensez à votre facturation !).

Nous allons simplement pouvoir retourner l’URL de l’image créée en response:

const image_url = img_res.data.data[0].url;

res.send({
    'summary': summary,
    'image': image_url
});

Et voilà ! Il vous suffit de lancer votre serveur, d’appeler la route avec le paragraphe de livre de votre choix, et tadaaaa !
L’image est probablement moche. Oui !

Mais c’est généré par GPT !