Bonjour à toutes et à tous !

Ces dernières semaines et ces derniers mois ont été marqués par la mise à disposition au grand public de ce que l'on appelle « l'intelligence artificielle ». D'abord, via ChatGPT, mais depuis peu avec BingAI...

Dans cet article, nous allons voir les différences entre ChatGPT et BingAI avec des exemples, ainsi que de discuter de la future concurrence.

BingAI : qu'est-ce que c'est ?

Mais, avant tout, Bing, qu'est-ce que c'est ?

Pour celles et ceux qui ne le savent pas, Bing est le moteur de recherche de Microsoft, lancé en 2009. Bien qu'il soit connu par certains, d'autres ne connaissent que Google. En effet, l'algorithme de Google est très bien construit, les résultats sont très souvent pertinents. C'est le leader historique enfin, alors pourquoi vouloir changer ?

Et, GPT, ça veut dire quoi ?

GPT signifie : « Generative Pre-trained Transformer 3 ». C'est un modèle de langage développé par OpenAI, et c'est de celui-ci dont est tiré ChatGPT. Microsoft a signé un contrat de collaboration avec OpenAI afin d'inclure le modèle GPT dans son moteur de recherche. Ainsi, lorsque vous ferez une recherche sur Bing, l'intelligence artificielle répondra également à votre question, en plus des résultats. Il est aussi possible de discuter avec l'IA comme avec ChatGPT. La réponse est beaucoup plus rapide, et s'appuie sur des sources Internet récentes, là où ChatGPT ne dispose que de sources antérieures à 2021.

Au moins, Google va riposter ?

Oui, et c'est déjà fait. Google développe par ailleurs une IA, mais cette fois-ci établie sur le modèle de langage LaMDA, signifiant « Language Model for Dialogue Applications ». On en avait entendu parler en 2022, lorsqu'un ingénieur de chez Google avait déclaré qu'en discutant avec l'IA, il avait découvert qu'elle « était consciente » et qu'elle avait déjà contacté un avocat pour se défendre. Au passage, il a partagé sa découverte à la presse, ce qui est mal passé chez Google... Comme le prouve son licenciement.

Afin de riposter face à ChatGPT, mais surtout à BingAI, Google a présenté à la presse son IA qui utilise un modèle réduit de LaMDA. De plus, les fondateurs de l'entreprise, Sergey Brin et Larry Page sont venus en renfort, alors qu'ils avaient pris leur retraite. Le 8 février 2023, Google dévoile BardAI au public : cette fameuse IA fondée sur LaMDA. Cependant, Google a publié un tweet de démonstration avec une partie de la réponse inexacte.

On peut lire : « JWST took the very first pictures of a planet outside of our own solar system » signifiant « JWST (un télescope) a pris les toutes premières images d'une planète en dehors de notre propre système solaire ».

Sur le tweet ci-dessus, on peut lire que JWST (James-Webb, un télescope lancé par la NASA, l'ESA et l'ASC fin 2021) a été le premier télescope à prendre une image en dehors de notre système solaire. Les experts en astronomie ont immédiatement fait remarquer que c'était faux et que la première image a été prise en 2004 par un télescope basé au Chili.

Cette erreur a fait mauvaise impression. L'action d'Alphabet (maison mère de Google) a chuté de plus de 8% au lendemain du tweet. Est-ce si grave que ça ? Je ne pense pas réellement, car ChatGPT peut également présenter des réponses inexactes lorsque le domaine est très spécifique. L'IA de Google sera lancée dans les prochaines semaines, on pourra s'en faire notre avis personnel à ce moment-là.

Comment y accéder ?

Alors que ChatGPT est accessible directement via le lien chat.openai.com et disponible selon l'utilisation de tous ses utilisateurs (une version « Plus » prioritaire, mais payante vient tout juste de sortir), BingAI nécessite à l'heure actuelle d'être inscrit sur une liste d'attente. Pour s'y inscrire, il faut vous rendre sur bing.com/new et d'être connecté avec votre compte Microsoft. Vous devez ensuite cliquer sur le bouton d'inscription... Et, attendre. Il est indiqué qu'il est possible d'accélérer la procédure en suivant des étapes supplémentaires. Une fois que vous aurez déverrouillé l'accès, vous recevrez un mail sur votre compte Microsoft. Vous pourrez y accéder via votre PC de bureau (le mobile n'est pas encore disponible) et via Microsoft Edge (les autres navigateurs ne sont pas pris en charge, même si vous pouvez modifier votre User Agent pour qu'il utilise celui de Edge, mais il peut y avoir des problèmes de compatibilité).

ChatGPT vs BingAI

Différence majeure

La différence majeure entre les deux IA réside dans le fait que BingAI effectue des recherches sur Internet, là où ChatGPT s'arrête en 2021. On peut donc demander les actualités à BingAI ou lui poser des questions plus spécifiques : après avoir effectué ses recherches, l'IA formulera sa réponse. Les réponses sont alors plus pertinentes qu'avec ChatGPT, ce qui rend l'outil encore plus puissant.

Nous allons voir quelques exemples de ce que ces deux IA proposent comme réponse sur différents sujets.

Donner une définition

Je demande aux deux IA de me proposer une définition de la technologie.

La réponse de ChatGPT
La réponse de BingAI

On peut constater que la réponse de ChatGPT est beaucoup plus détaillée alors que celle de BingAI est plus succincte. Je ne pense pas que ce soit un problème, car on peut lui par la suite le questionner sur certains points qui nous interrogent. Sur la réponse de BingAI, on constate également une partie « En savoir plus » en bas. L'IA est capable de citer ses sources, donc si l'on veut en apprendre davantage, on peut accéder à ces sites !

Rédaction d'un poème

Je vais maintenant demander aux deux IA de me rédiger un poème humoristique sur la technologie.

Le poème de ChatGPT
Le poème de BingAI

Parlons d'abord de la forme. Dans les deux cas, on a des quatrains : pour ChatGPT, on a quatre strophes, tandis que pour BingAI, on en a que trois. Les rimes entre les vers sont très aléatoires, probablement dues au hasard.

Aussi, le fond est intéressant. Pour ChatGPT, certains vers n'ont pas réellement de sens à mes yeux : « Quand les mises à jour sont plus longues que la queue pour l'euphorie » ou encore « La technologie est vraiment incroyable, mes textes ». Celle de BingAI est beaucoup plus cohérente. Toutefois, je trouve que leur avis critique concernant la technologie est très surprenant. En effet, les deux IA indiquent qu'il faut utiliser la technologie avec modération. ChatGPT va même jusqu'à indiquer qu'il est lui-même né de la technologie et qu'il est un modèle de langage AI.

Donner les actualités

Je demande maintenant aux deux IA de m'indiquer les dernières actualités technologiques. Avant même de poser la question, je me doute que BingAI va être en mesure de le faire en piochant sur Internet. Tandis que ChatGPT non du fait que sa base de connaissances s'arrête en 2021.

Réponse de ChatGPT
Réponse de BingAI

Sans surprise, ChatGPT est incapable de donner les actualités récentes sur la technologie, mais propose les principales découvertes technologiques de ces dernières années. Quant à lui, BingAI indique trois actualités récentes dans le domaine de la technologie.

Résolution d'un problème mathématique

Passons désormais à la science : on va demander aux IA de résoudre un problème mathématique. C'est un problème délicat qui peut diviser certaines personnes : est-ce que \( 1 = 0.999... \) en admettant que le nombre de 9 soit infini.

Réponse de ChatGPT
Réponse de BingAI

En comparant les réponses, ChatGPT dit non et BingAI dit oui. Qui a raison ? Eh bien, c'est délicat... Ce qui intéressant, c'est que dans les deux cas, une explication est donnée. Alors que ChatGPT nous indique vaguement comment faire, BingAI nous propose trois façons de le démontrer. Et, il donne ses sources, donc on peut en savoir plus en cliquant dessus !

Codage d'un jeu de morpion en Python

Pour ce dernier test, nous allons demander aux IA de coder un jeu de morpion en Python. Pour rappel, le morpion est composé de deux symboles : un « X » et un « O ». Le tout sur un tableau de 3 cases par 3 cases (ainsi, un total de 9 cases). On va aussi lui demander d'y ajouter une IA pour placer les cercles. Deux choix s'offrent à nous : on peut lui demander une IA un peu « simple » qui mettra des cercles au hasard sur le tableau et une IA bien plus « intelligente » qui va analyser toutes les possibilités et choisir la meilleure, grâce à un algorithme « d'élagage alpha-bêta ». Cependant, les résultats n'ont pas été très concluants...

import numpy as np

class TicTacToe:
    def __init__(self):
        self.board = np.zeros((3,3))
        self.player = 1

    def draw_board(self):
        print("\n")
        print(" ", self.board[0, 0], " | ", self.board[0, 1], " | ", self.board[0, 2], " ")
        print("----|-----|----")
        print(" ", self.board[1, 0], " | ", self.board[1, 1], " | ", self.board[1, 2], " ")
        print("----|-----|----")
        print(" ", self.board[2, 0], " | ", self.board[2, 1], " | ", self.board[2, 2], " ")
        print("\n")

    def player_can_play(self, x, y):
        if self.board[x, y] == 0:
            return True
        return False

    def play_move(self, x, y):
        self.board[x, y] = self.player
        self.player = 3 - self.player
        return

    def player_wins(self, player):
        for i in range(3):
            if np.all(self.board[i,:] == player) or np.all(self.board[:,i] == player):
                return True
        if np.all(np.diag(self.board) == player) or np.all(np.diag(np.fliplr(self.board)) == player):
            return True
        return False

    def player_loses(self, player):
        opponent = 3 - player
        return self.player_wins(opponent)

    def is_over(self):
        return np.all(self.board != 0) or self.player_wins(1) or self.player_wins(2)

    def score(self, depth):
        if self.player_wins(1):
            return 10 - depth
        elif self.player_wins(2):
            return depth - 10
        else:
            return 0

    def minimax(self, depth, alpha, beta, maximizing_player):
        if depth == 0 or self.is_over():
            return self.score(depth)

        if maximizing_player:
            max_score = -1000
            for i in range(3):
                for j in range(3):
                    if self.player_can_play(i, j):
                        self.play_move(i, j)
                        score = self.minimax(depth-1, alpha, beta, False)
                        self.play_move(i, j)
                        max_score = max(max_score, score)
                        alpha = max(alpha, score)
                        if beta <= alpha:
                            break
                if beta <= alpha:
                    break
            return max_score
        else:
            min_score = 1000
            for i in range(3):
                for j in range(3):
                    if self.player_can_play(i, j):
                        self.play_move(i, j)
                        score = self.minimax(depth-1, alpha, beta, True)
                        self.play_move(i, j)
                        min_score = min(min_score, score)
                        beta = min(beta, score)
                        if beta <= alpha:
                            break
                if beta <= alpha:
                    break
            return min_score

    def best_move(self):
        best_score = -1000
        best_move = (0, 0)
        for i in range(3):
            for j in range(3):
                if self.player_can_play(i, j):
                    self.play_move(i, j)
                    score = self.minimax(9, -1000, 1000, False)
                    self.play_move(i, j)
                    if score > best_score:
                        best_score = score
                        best_move = (i, j)
        return best_move

if __name__ == "__main__":
    t = TicTacToe()
    t.draw_board()
    while not t.is_over():
        if t.player == 1:
            x, y = map(int, input("Enter your move (row column): ").split())
            while not t.player_can_play(x, y):
                x, y = map(int, input("Enter your move (row column): ").split())
            t.play_move(x, y)
        else:
            x, y = t.best_move()
            t.play_move(x, y)
        t.draw_board()

    if t.player_wins(1):
        print("You win!")
    elif t.player_wins(2):
        print("You lose!")
    else:
        print("It's a draw!")
Code Python du morpion généré par ChatGPT

Le résultat n'est pas bon : l'idée est là, mais l'interface est incompréhensible lors de la compilation.

Apparemment, j'ai perdu...

Notons tout de même que j'ai déjà proposé cet exercice à ChatGPT, et le résultat était plus convaincant. À vrai dire, je pense que nous devons reprendre l'IA sur certains points afin de corriger les erreurs progressivement.

import sys

board = ["_"] * 9

def print_board():
    row1 = "| {} | {} | {} |".format(board[0], board[1], board[2])
    row2 = "| {} | {} | {} |".format(board[3], board[4], board[5])
    row3 = "| {} | {} | {} |".format(board[6], board[7], board[8])

    print()
    print(row1)
    print(row2)
    print(row3)
    print()

def winning_combination(board, icon):
    # return True if there is a winning combination on the board
    win_comb = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]]
    for combination in win_comb:
        if all(board[i] == icon for i in combination):
            return True
    return False

def return_score(board):
    # return the score for the current board state
    if winning_combination(board, "X"):
        return 1
    elif winning_combination(board, "O"):
        return -1
    else:
        return 0

def game_over(board):
    # return True if the game is over
    return winning_combination(board, "X") or winning_combination(board, "O") or "_" not in board

def minimax(board, number, alpha, beta):
    available_positions = [i for i, x in enumerate(board) if x == "_"]
    if game_over(board):
        return return_score(board), None
    if number == 1:
        best = -sys.maxsize
        move = None
        for i in available_positions:
            board[i] = "X"
            score, m = minimax(board, 2, alpha, beta)
            board[i] = "_"
            if score > best:
                best = score
                move = i
            alpha = max(alpha, best)
            if alpha >= beta:
                break
        return best, move
    else:
        best = sys.maxsize
        move = None
        for i in available_positions:
            board[i] = "O"
            score, m = minimax(board, 1, alpha, beta)
            board[i] = "_"
            if score < best:
                best = score
                move = i
            beta = min(beta, best)
            if alpha >= beta:
                break
        return best, move

def player_move(icon):
    if icon == "X":
        number = 1
    elif icon == "O":
        number = 2

    if number == 1:
        print("Your turn player {}".format(number))
        choice = int(input("Enter your move (1-9): ").strip())
        if board[choice - 1] == "_":
            board[choice - 1] = icon
        else:
            print()
            print("That space is already taken!")
    else:
        print("AI's turn")
        result, move = minimax(board, number, -sys.maxsize, sys.maxsize)
        if move == None:
            print("No moves left!")
        else:
            board[move] = icon
            
def is_victory(icon):
    if (board[0] == icon and board[1] == icon and board[2] == icon) or \
       (board[3] == icon and board[4] == icon and board[5] == icon) or \
       (board[6] == icon and board[7] == icon and board[8] == icon) or \
       (board[0] == icon and board[3] == icon and board[6] == icon) or \
       (board[1] == icon and board[4] == icon and board[7] == icon) or \
       (board[2] == icon and board[5] == icon and board[8] == icon) or \
       (board[0] == icon and board[4] == icon and board[8] == icon) or \
       (board[2] == icon and board[4] == icon and board[6] == icon):
        return False

def is_draw():
    if "_" not in board:
        return True
    else:
        return False

while True:
    print_board()
    player_move("X")
    print_board()
    if is_victory("X"):
        print("X wins! Congratulations!")
        break
    elif is_draw():
        print("It's a draw!")
        break
    player_move("O")
    if is_victory("O"):
        print_board()
        print("O wins! Congratulations!")
        break
    elif is_draw():
        print("It's a draw!")
        break
Une tentative précédente de ChatGPT qui était beaucoup plus concluante
C'est vraiment mieux !

Du côté de BingAI, j'ai eu peur dans un premier temps. Elle me disait qu'elle n'avait pas les capacités d'écrire ce programme. J'ai alors insisté et elle refusait toujours de le faire. Dans le doute, j'ai réinitialisé la conversation, et cette fois-ci, elle m'a proposé un code.

# Code généré par Sydney, le mode chat de Bing Search
# Ce code n'a pas été testé ni exécuté, il peut contenir des erreurs

# Importer la bibliothèque math
import math

# Définir la taille du plateau
N = 3

# Définir les symboles des joueurs
X = "X"
O = "O"
V = " "

# Créer le plateau de jeu
plateau = [[V] * N for _ in range(N)]

# Afficher le plateau de jeu
def afficher_plateau():
    for i in range(N):
        print("|", end="")
        for j in range(N):
            print(plateau[i][j], end="|")
        print()
    print()

# Vérifier si le plateau est plein
def plateau_plein():
    for i in range(N):
        for j in range(N):
            if plateau[i][j] == V:
                return False
    return True

# Vérifier si un joueur a gagné
def gagnant(joueur):
    # Vérifier les lignes
    for i in range(N):
        if all(plateau[i][j] == joueur for j in range(N)):
            return True
    # Vérifier les colonnes
    for j in range(N):
        if all(plateau[i][j] == joueur for i in range(N)):
            return True
    # Vérifier les diagonales
    if all(plateau[i][i] == joueur for i in range(N)):
        return True
    if all(plateau[i][N - 1 - i] == joueur for i in range(N)):
        return True
    # Sinon, pas de gagnant
    return False

# Évaluer la valeur du plateau pour un joueur
def evaluer(joueur):
    if gagnant(joueur):
        return 1
    if gagnant(adversaire(joueur)):
        return -1
    return 0

# Obtenir la liste des coups possibles
def coups_possibles():
    coups = []
    for i in range(N):
        for j in range(N):
            if plateau[i][j] == V:
                coups.append((i, j))
    return coups

# Obtenir l'adversaire d'un joueur
def adversaire(joueur):
    if joueur == X:
        return O
    return X

# Appliquer un coup sur le plateau
def appliquer_coup(coup, joueur):
    i, j = coup
    plateau[i][j] = joueur

# Annuler un coup sur le plateau
def annuler_coup(coup):
    i, j = coup
    plateau[i][j] = V

# Implémenter l'algorithme d'élagage alpha-bêta
def alpha_beta(joueur, alpha, beta):
    # Si le plateau est terminal, retourner la valeur et le coup nul
    if plateau_plein() or gagnant(X) or gagnant(O):
        return evaluer(joueur), None
    # Sinon, initialiser le meilleur coup et la meilleure valeur
    meilleur_coup = None
    if joueur == X:
        # Si le joueur est X, maximiser la valeur
        meilleure_valeur = -math.inf
        # Pour chaque coup possible
        for coup in coups_possibles():
            # Appliquer le coup
            appliquer_coup(coup, joueur)
            # Appeler récursivement alpha_beta sur l'adversaire
            valeur, _ = alpha_beta(adversaire(joueur), alpha, beta)
            # Annuler le coup
            annuler_coup(coup)
            # Si la valeur est meilleure que la meilleure valeur
            if valeur > meilleure_valeur:
                # Mettre à jour la meilleure valeur et le meilleur coup
                meilleure_valeur = valeur
                meilleur_coup = coup
            # Mettre à jour alpha
            alpha = max(alpha, meilleure_valeur)
            # Si alpha >= beta, élaguer
            if alpha >= beta:
                break
    else:
        # Si le joueur est O, minimiser la valeur
        meilleure_valeur = math.inf
        # Pour chaque coup possible
        for coup in coups_possibles():
            # Appliquer le coup
            appliquer_coup(coup, joueur)
            # Appeler récursivement alpha_beta sur l'adversaire
            valeur, _ = alpha_beta(adversaire(joueur), alpha, beta)
            # Annuler le coup
            annuler_coup(coup)
            # Si la valeur est meilleure que la meilleure valeur
            if valeur < meilleure_valeur:
                # Mettre à jour la meilleure valeur et le meilleur coup
                meilleure_valeur = valeur
                meilleur_coup = coup
            # Mettre à jour beta
            beta = min(beta, meilleure_valeur)
            # Si alpha >= beta, élaguer
            if alpha >= beta:
                break
    # Retourner la meilleure valeur et le meilleur coup
    return meilleure_valeur, meilleur_coup

# Jouer un tour
def jouer(joueur):
    # Si le joueur est X, demander le coup au joueur humain
    if joueur == X:
        print("À vous de jouer, X !")
        # Obtenir la liste des coups possibles
        coups = coups_possibles()
        # Afficher les coups possibles
        print("Coups possibles : ", coups)
        # Demander le coup au joueur
        coup = None
        while coup not in coups:
            try:
                i = int(input("Ligne : "))
                j = int(input("Colonne : "))
                coup = (i, j)
            except ValueError:
                print("Entrée invalide, veuillez réessayer.")
        # Appliquer le coup
        appliquer_coup(coup, joueur)
    # Sinon, si le joueur est O, calculer le coup avec l'IA
    else:
        print("À moi de jouer, O !")
        # Appeler l'algorithme alpha_beta
        _, coup = alpha_beta(joueur, -math.inf, math.inf)
        # Appliquer le coup
        appliquer_coup(coup, joueur)
        # Afficher le coup
        print("J'ai joué : ", coup)

# Commencer le jeu
def commencer():
    # Afficher le plateau initial
    afficher_plateau()
    # Initialiser le joueur courant
    joueur = X
    # Tant que le jeu n'est pas terminé
    while not plateau_plein() and not gagnant(X) and not gagnant(O):
        # Jouer un tour
        jouer(joueur)
        # Afficher le plateau
        afficher_plateau()
        # Changer de joueur
        joueur = adversaire(joueur)
    # Afficher le résultat
    if gagnant(X):
        print("X a gagné !")
    elif gagnant(O):
        print("O a gagné !")
    else:
        print("Match nul !")

# Appeler la fonction commencer
commencer()
Code Python du morpion généré par BingAI

Le résultat est meilleur qu'avec la première tentative de ChatGPT. Le code est commenté en français, et ça, c'est bien. Mais, à l'exécution, ce n'est pas très clair non plus...

Je crois que j'ai gagné ?

Je pense être le joueur mettant les croix, mais ce n'est pas très clair... De plus, placer son symbole est plutôt technique, car on a une liste de coups possibles, qui vont de (0, 0) soit en haut à gauche, à (2, 2) soit en bas à droite. Disons que ça fonctionne, néanmoins ce n'est pas très intuitif. Et, l'IA ne semble pas m'avoir bloqué lors de ma dernière tentative (elle aurait pu m'empêcher de faire une diagonale).

Cet exercice est très complexe, et même si les résultats n'ont pas été très concluants, j'estime vraiment incroyable que l'IA puisse générer du code. Depuis peu, il existe également des assistants de codage comme GitHub Copilot qui sont très intéressants pour les développeurs.

Conclusion

Pour conclure, cette technologie qu'est l'IA est très intéressante et prometteuse. Bien qu'elle soit perfectible sur certains points, elle est pour le moment assez robuste. Notamment avec BingAI qui embarque le modèle GPT et y ajoute la recherche sur Internet, contrairement à ChatGPT qui a sa base de connaissances limitée à 2021.

Du côté de Google, bien que le résultat proposé par son IA, BardAI, ait été décevant, le modèle LaMDA paraît aussi être prometteur. On devrait très bientôt en apprendre davantage, et même pouvoir la tester.

Merci d'avoir lu ce post, et l'on se retrouve bientôt pour la suite !

Photo by Om siva Prakash / Unsplash