Sébastien L'haire - Staf 24: stage - sept. 2000

Rapport de stage

1. Introduction

Le stage que j'ai effectué au Laboratoire d'Analyse et de Technologie du Langage (LATL) de l'Université de Genève avait pour objet le développement du logiciel GENE, qui est une interface avec le générateur automatique de phrases GBGEN. Il a eu lieu de novembre 1999 à juin 2000. Le temps de travail consacré à ce projet a été très variable. En effet, j'y ai consacré parfois une trentaine d'heures par semaine, parfois aucune, et quand le rythme était normal 15 à 20 heures. Le travail réalisé dans le cadre de ce stage représente grosso modo un temps plein pendant un peu moins de deux mois pour une personne.

Ceci est dû au fait que le LATL est aussi mon employeur. J'y suis en effet engagé en tant qu'assistant candidat doctorant sur un projet de traduction automatique. Mon travail professionnel a donc souvent pris le dessus sur le travail de stage.

2. Présentation du laboratoire

Avant d'aller plus loin, je souhaite présenter plus en détail le lieu du stage. Comme cela a déjà été mentionné, le Laboratoire d'Analyse et de Technologie du Langage (LATL) appartient à l'Université de Genève. Il est rattaché au département de linguistique de la Faculté des Lettres. Certains de ses membres enseignent la linguistique ou l'informatique dans le cadre de la Faculté.

Fondé au début des années 1990 par le professeur Eric Wehrli, le LATL compte aujourd'hui une douzaine de collaboratrices et de collaborateurs. Il est actif dans le domaine du traitement automatique du langage naturel (TALN). Dans ce cadre, le LATL développe des outils d'analyse, d'étiquetage (tagging), de traduction automatique, de synthèse de la parole, de génération automatique, ainsi que des applications dans le domaine de l'enseignement des langues par ordinateur. Les langues principales de travail sont le français et l'anglais, mais il y a aussi des projets sur l'allemand, l'italien, l'espagnol, le grec moderne, le basque et le vietnamien.

3. Direction du stage

La direction du stage était assurée par:

Ces deux responsables m'ont laissé une très large autonomie. Au sein du laboratoire, j'ai eu principalement recours à l'aide et aux conseils avisés de Thierry Etchegoyhen (assistant, responsable du générateur GBGEN) et d'Arnaud Gaudinat (assistant, ingénieur en informatique).

4. Le système GBGEN

Avant de décrire le mandat et sa réalisation, il est indispensable de survoler la question de la génération et du système GBGEN.

La génération consiste à faire écrire automatiquement par un ordinateur des phrases grammaticalement correctes à partir de représentations sémantiques ou de données. Un générateur sera utilisé par exemple dans les cas suivants, très sommairement expliqués:

Le LATL a développé un système de génération à large échelle qui est notamment utilisé pour la traduction automatique: le système GBGEN. GBGEN est un générateur déterministe, c'est-à-dire qu'il ne crée qu'une et une seule structure grammaticale à partir de la structure d'entrée.

Les structures d'entrée du générateur sont appelées "structures pseudo-sémantiques" (Pseudo-Semantic Structures, PSS). Il s'agit de structures abstraites complexes, représentant des phrases, des groupes nominaux et des modifieurs (adjectifs ou adverbes). Les PSS combinent des informations abstraites avec des informations lexicales. Les informations abstraites codent notamment le genre, le nombre et le type de déterminant utilisé pour les noms, la personne, le temps ou l'aspect pour les verbes etc. Les informations lexicales sont des mots des classes lexicales ouvertes (verbe, substantif, adverbe ou adjectif), qu'il est très difficile de représenter de manière abstraite. Les PSS sont divisées en trois sous-classes, qui correspondent à ces classes lexicales ouvertes:

Une PSS peut avoir des satellites, qui sont d'autres PSS qui lui sont reliées par une fonction sémantique ou thématique. Il peut s'agir:

Ces structures préservent la sémantique profonde d'une phrase. Ainsi, les phrases "le chat mange la souris" et "la souris est mangée par le chat" auront la même structure interne, excepté le champ de la voix (actif ou passif).

Voici pour terminer la structure de la phrase "Hier le chat a mangé la souris", telle qu'elle est affichée par le système central utilisé par le LATL, avec nos commentaires:

PSS[{ }           Début de la PSS principale
  CLS[         Début de la phrase principale
    Mood real     Mode de la phrase : réel (peut être irréel pour le conditionnel et le subjonctif)
    Tense E = S     Le temps d'énonciation est égal au temps où l'action a lieu
    InfoFunction categorical     La phrase a une valeur prédicative
    Modality undefined     La modalité (obligation, possibilité...) n'est pas définie
    Aspect (non progressive, perfective)     En français, le passé composé indique un aspect perfectif
    Voice active     Voix active
    Causative not causative     La proposition n'est pas causative (cf. "Jean a fait se laver les dents aux enfants")
    Negation not negated     La proposition n'est pas niée
    Utterance type declaration     La proposition est déclarative (peut être interrogative, impérative).
    Predicate manger     Information lexicale
  ]CLS          
  Satellites{         Liste des satellites
    PSS[{ }       PSS du 1er argument du verbe
      Theta role agent   L'argument est l'agent du verbe: celui qui commet l'action de manger
      DPS[      
        Property chat Info lexicale
        Operator the Le déterminant est un article défini
        Number singular Le nom est au singulier
        Ref. index   L'indice référentiel n'est pas défini. Il est utilisé par exemple dans le cas de relatives pour lier le pronom à son antécédent ("la personnei quei je connais").
      ]DPS      
    ]PSS        
    PSS[{ }       PSS du 2e argument du verbe
      Theta role theme   L'argument est le thème: ce qui subit l'action d'être mangé
      DPS[      
        Property souris  
        Operator the  
        Number singular  
        Ref. index    
      ]DPS      
    ]PSS        
    PSS[{ topic }       3e satellite, topicalisé, c'est-à-dire placé en début de phrase.
      Value when   La PSS a une valeur temporelle
      Scope sentential   La PSS porte sur la phrase entière
      CHS[      
        Characteristic hier Information lexicale
      ]CHS      
    ]PSS        
  }         Fin de la liste des satellites
]PSS           Fin de la PSS principale et de la phrase

Comme on peut s'en rendre compte, ces structures sont très complexes et peu lisibles pour le profane. Elles peuvent être affichées par le système, mais bien entendu, une application grand public, comme un traducteur, ne les affichera pas.

Le système GBGEN a surtout été réalisé sur la machine centrale du laboratoire. Il n'a pas eu une version PC digne de ce nom. En effet, seule une interface extrêmement rustique a été réalisée, pour une version obsolète du générateur, qui n'offrait pas de fonctions ou d'interactivité particulières. L'utilisateur n'a d'autres possibilités que d'entrer une phrase au clavier et de voir les différentes étapes de l'analyse et de la génération à travers un affichage sommaire. Des applications de traduction ont été réalisées, mais rien ne permet en l'état d'interagir avec le générateur en tant que tel.

5. Mandat

Dans le cadre de mes obligations professionnelles, il paraissait préférable et nécessaire de me trouver, pour mon stage, une application éducative à développer au laboratoire, qui offrait de la souplesse pour que je puisse, selon les moments, porter mes efforts principalement sur le stage ou sur le projet pour lequel je suis engagé. Mes centres d'intérêt me poussaient également à réaliser une application d'apprentissage des langues à l'aide d'outils de traitement du langage.

Le LATL ressentait depuis un certain temps le besoin d'une interface facile d'utilisation pour le générateur GBGEN. C'est pourquoi mon stage a porté sur le projet GENE, interface pour le générateur GBGEN. Cette interface devait pouvoir être utilisée dans deux cas:

Le mandat du stage comprenait donc la réalisation de cette interface. Le choix s'est porté sur l'interface de programmation Delphi, qui utilise le langage Pascal-Objet, que je connais et maîtrise déjà suffisamment.

En outre, il fallait aussi adapter le générateur pour qu'il fonctionne sur un PC, ce qui n'a pas été fait depuis longtemps. En effet, les structures et techniques du générateur ont considérablement changé entre-temps. La technique adoptée est de créer un programme sous forme de DLL (Dynamic Link Library). Les DLL sont des séries de fonctions qui peuvent être appelées par plusieurs programmes sous Windows, et qui sont donc partagées.

La tâche devait être réalisée dans le cadre d'un mi-temps. La durée du stage n'a pas été fixée avec précision, vu l'ampleur de la tâche. Il a aussi été tacitement convenu que le stage pouvait prendre fin même si la tâche n'était pas encore terminée: attendu que je travaille déjà sur place, j'ai une souplesse dans mon emploi du temps et je peux terminer l'application quand j'ai du temps.

6. Réalisation

Phase 1: conception générale

Dans une première phase, j'ai dû me familiariser avec le fonctionnement du générateur et de ses structures. Il n'est en effet pas trivial de comprendre le fonctionnement d'un tel système. En même temps, il a fallu penser aux fonctionnalités et à l'interface de GENE.

Dans cette phase, j'ai dû consulter la documentation existante et m'entretenir avec le responsable du système, afin de ne pas partir dans une mauvaise direction et de connaître les contraintes à respecter.

Parallèlement, j'ai aussi commencé à réaliser une idée que j'avais en tête pour l'interface. Comme on l'a vu plus haut, les structures utilisées par le générateur sont organisées hiérarchiquement. La PSS principale contient des satellites, qui peuvent eux-mêmes contenir d'autres satellites et ainsi de suite. Afin de ne pas être perdu dans cette hiérarchie, il est nécessaire de la représenter d'une manière ou d'une autre.

Parmi les composants standards offerts par la plate-forme Windows, il y a une vue arborescente, qui est très largement utilisée. Par exemple, la structure des répertoires d'un disque dans l'application "Explorateur" est représentée par cette vue arborescente. L'utilisateur peut masquer ou faire apparaître certains niveaux de la hiérarchie. En outre, des images et du texte peuvent être associés aux "feuilles" de la hiérarchie. A tout point de vue, la vue arborescente m'a semblé le meilleur outil pour représenter l'imbrication des PSS entre elles.

J'ai donc commencé à réaliser un petit programme de test de type MDI (Multiple Documents Interface). Sous ce nom abscons se cachent simplement les programmes, comme la plupart des traitements de texte, qui contiennent eux-mêmes des fenêtres dites "fenêtres-filles" qui dépendent d'eux. La plupart du temps, ces fenêtres seront des documents, mais ce n'est pas obligatoire. La fenêtre principale de mon programme de test contenait simplement deux boutons permettant de créer des fenêtres, et une vue arborescente.

Mon but était simplement d'associer chaque feuille de la vue arborescente avec une fenêtre-fille, et inversement. Ainsi, en cliquant sur une des feuilles de la vue arborescente, la fenêtre-fille associée devait apparaître en premier plan, et en cliquant sur une fenêtre, la feuille correspondante devait être sélectionnée, c'est-à-dire apparaître en inversé.

La réalisation de ce prototype était très importante. Si j'avais échoué dans sa réalisation, il aurait fallu concevoir un autre type d'interface, ce qui était problématique. Ce système est simple à décrire, il n'a par contre pas été facile à réaliser. En effet, il a fallu tâtonner pendant de nombreuses heures avant de trouver une solution. J'ai notamment fait appel à un newsgroup consacré à la programmation en Delphi. On verra par la suite que j'avais négligé une difficulté supplémentaire qui m'a également coûté pas mal de sueur.

Enfin, dans cette phase, j'ai pris contact au cours du mois de mai avec mon tuteur Pierre Dillenbourg pour lui présenter le (maigre) résultat de mes travaux et mes projets pour la suite. La discussion a été animée, car Pierre a émis de sérieux doutes sur la valeur et l'utilité pédagogique de mon projet. Ses arguments ont été convaincants et nous nous sommes mis d'accord sur la tâche à réaliser, sur la durée du stage et sur l'articulation de mon stage avec mon mémoire. Le stage devait s'arrêter fin juin, que le programme soit réalisé ou non. Ce délai me laissait environ 5 semaines de travail.

Cette phase a été extrêmement étendue dans le temps. La première phase a commencé autour du mois de novembre 1999, elle a pris fin en mai 2000! On peut évaluer la somme de travail à deux à trois semaines à plein temps. Je reviendrai plus tard sur les raisons de ce retard.

Phase 2: réalisation de l'interface

Il était temps de passer à la phase 2. Vu que le prototype d'interface avait donné des résultats plutôt satisfaisants, j'ai pu aller de l'avant dans la réalisation du programme proprement dit. Il s'agissait simplement et uniquement de faire une interface, sans pour l'instant la connecter avec le générateur.

Simplifiant les structures utilisées par GBGEN, j'ai simplement prévu quatre fenêtres fille différentes, une pour chaque sous-type de PSS (CLS, DPS, CHS) et une pour la coordination (et / ou). Dans chaque fenêtre, les champs nécessaires au remplissage des PSS sont présents. J'ai désigné les fenêtres par des termes grammaticaux plus classiques: les CLS sont appelées "Predicate structure", les DPS "Noun structure" et les CHS "Modifier structure". Pour des raisons de commodité, j'ai réalisé l'interface en anglais, mais il serait relativement facile de traduire l'interface en français ou de donner le choix à l'utilisateur.

Le programme principal apparaît avec des menus, un champ où sera affichée la phrase générée, et des boutons pour créer une structure. En dessous à gauche, dans l'espace de travail où sont créées les fenêtres-filles, apparaît la vue hiérarchique de la phrase.

Lorsqu'on appuie sur un des boutons, une fenêtre de dialogue apparaît pour que l'utilisateur entre l'élément lexical pour la structure créée. Dans un premier temps, le mot n'était pas recherché dans le lexique, mais cette fonction a été introduite dans une phase ultérieure.

Voici l'interface telle qu'elle était à la fin du stage:

La vue arborescente de droite montre la relation entre le verbe manger et son argument, qui sera en l'occurrence le sujet du verbe.

Phase 3: traitement de la coordination

Pour la troisième phase, j'ai traité du problème de la coordination, qui est un cas particulier. J'ai fait le choix de ne donner à l'utilisateur la possibilité d'introduire une coordination que lorsque le premier élément coordonné était entré. Ainsi, dans la fenêtre principale, il n'y a pas de bouton pour créer une coordination. C'est uniquement dans les fenêtres de prédicat etc. que cette possibilité existe. Cette manière de faire m'a paru plus à l'épreuve des utilisateurs imprévisibles.

Par contre, il fallait dans ce cas introduire un noeud intermédiaire dans la représentation hiérarchique, en décalant le premier élément coordonné. Ce qui ne paraît pas compliqué conceptuellement était plus difficile à réaliser du point de vue informatique. De plus, le composant de la vue hiérarchique offert par Delphi comprenait un bug dans la fonction que je voulais utiliser. C'est ainsi que j'ai pataugé et perdu plus de temps qu'il n'en fallait, avant de tomber sur Internet sur la description du bug et sur sa correction.

Avant de finir cette phase, j'ai réalisé que je n'avais pas réfléchi à la suppression des fenêtres. Il a donc fallu, avant d'aller plus loin, régler ce problème. Si la fenêtre constitue un noeud terminal, la suppression ne pose pas de problèmes. Mais il a fallu penser à détruire des nœuds qui avaient des enfants, et donc prévoir une destruction des noeuds et des fenêtres qui leur étaient associées par une procédure récursive.

Phase 4: liaison avec le lexique

Le LATL a déjà créé un certain nombre de versions Windows de ses programmes. Ceux-ci accèdent au même lexique pour chaque langue. La procédure de recherche d'un mot est également générique.

Les DLL déjà créées ne proposaient pas de recherche dans le lexique. Il a donc fallu définir de nouvelles fonctions à exporter. Après quelques tâtonnements pour assurer la compatibilité entre les structures de données exportées par la procédure et les structures utilisées par GENE, j'ai simplement créé une procédure d'interfaçage basée sur les procédures existantes.

Ensuite, il a fallu faire une procédure de sélection des lexèmes. Les lexèmes sont la forme canonique d'un mot. Ainsi, le mot "mangerais" a pour lexème le verbe "manger"; il est à la première et deuxième personne du conditionnel. "Manger" a deux lexèmes, selon sa sous-catégorisation, c'est-à-dire les constructions qu'il admet: une construction absolue (Jean mange) ou avec un complément d'objet direct (Jean mange une pomme).

Autre cas de figure, "couvent" peut renvoyer à des lexèmes de catégorie différente: le verbe "couver" ou le substantif "couvent". Selon que l'utilisateur veut créer une DPS ou une CLS, une des alternatives devra être éliminée.

Une fenêtre invite l'utilisateur à faire son choix parmi les solutions valides:

 

Phase 5: création automatique de fenêtres

Il serait fastidieux pour l'utilisateur de devoir ajouter manuellement chaque argument d'un verbe, d'un adjectif ou d'un adverbe. Ensuite, en phase de génération, un oubli ou une erreur dans cette opération serait une source d'erreurs inutiles.

C'est pourquoi il m'a paru préférable de générer automatiquement les PSS satellites, selon le lexème de la PSS parente. Ainsi, les arguments sont créés dans l'ordre de la sous-catégorisation, avec le bon rôle thématique. L'utilisateur n'aura ensuite qu'à choisir le lexème souhaité pour la phrase qu'il voudra générer.

Phase 6: remplissage des PSS

Enfin, nous arrivons à la dernière phase que j'ai pu réaliser dans le temps qui m'était imparti. Il fallait maintenant créer les PSS d'interface qui devront être passées au générateur. Comme nous l'avons dit, les structures présentées à l'utilisateur sont quelque peu simplifiées. Il faut donc remplir correctement les structures, de manière transparente pour l'utilisateur. Cette phase est aussi le dernier moment pour vérifier que rien n'a été oublié dans l'interface et que les simplifications de structures prévues sont efficaces.

Cette phase n'a pas pu être terminée. Les structures en jeu sont complexes. Il faut également relier les PSS entre elles et pouvoir les supprimer correctement.

7. A réaliser

Pour information, voici les dernières phases à réaliser. La phase 6 doit encore être terminée.

Phase 7: DLL

La DLL du système doit être encore réalisée. Rappelons que le système GBGEN fonctionne déjà sur la machine centrale du laboratoire. Pour les versions PC, nous disposons d'un compilateur du langage de programmation Modula-2 utilisé sur notre système principal. La plupart des modules de génération, d'analyse, de traduction etc. sont en principe indépendants du système d'exploitation et du processeur. Seuls certains modules de bas niveau sont différents d'un système à l'autre.

Il faudra donc vérifier que les importants changements de structures intervenus les deux dernières années sont bien compatibles avec la version PC. L'exportation de procédures dans une DLL peut parfois poser certains problèmes. De plus, l'expérience que j'ai eue avec la création de la procédure de consultation du lexique a montré que l'on peut rencontrer certaines difficultés pour passer des structures d'un langage à l'autre. Les PSS sont des structures complexes de nature analogue à celles utilisées par le lexique. L'expérience déjà acquise avec le lexique devrait donc permettre de gagner un peu de temps.

Phase 8: tests de fiabilité

Enfin, avant d'utiliser le programme pour des expériences en vue du mémoire, il faudra que le programme soit le plus stable possible Le programme devra donc être testé avec une série de phrases, et particulièrement celles qui serviront pour l'expérience qui servira de base au mémoire.

8. Difficultés rencontrées

Les difficultés rencontrées ont été de deux ordres. Des difficultés techniques et des difficultés d'organisation.

Difficultés techniques

La réalisation de A à Z d'un logiciel n'est parfois pas très aisée. J'ai néanmoins réussi à obtenir l'aide nécessaire, soit dans le laboratoire même, soit ailleurs en cherchant sur Internet.

On peut évoquer par exemple les difficultés de conception. Il faut imaginer une interface la plus claire possible, essayer d'être cohérent dans l'ensemble des menus et interfaces. Certaines variables des structures que je devais interfacer étaient plutôt complexes.

Quant aux difficultés de programmation, elles sont venues principalement d'un bug d'une composante du compilateur. Là, j'ai perdu un temps précieux. Une autre difficulté a été de transmettre des données entre DLL et programme. Au laboratoire, personne n'avait l'expérience de DLL gérant des structures si complexes. Finalement, en tâtonnant, j'ai pu trouver une solution adéquate.

Difficultés d'organisation

Dans ce projet, j'ai rencontré surtout des difficultés d'organisation. En effet, comme je l'ai déjà dit, je devais travailler, dans le même laboratoire, pour un projet impliquant trois personnes. J'étais payé pour ce projet, et, bien que ma tâche soit secondaire et autonome par rapport aux tâches des autres participants, mes collègues avaient néanmoins besoin des interfaces que je réalisais. Il y a aussi de nombreuses tâches secondaires, imprévues et imprévisibles. Je n'ai pas réussi à travailler régulièrement pour mon stage un ou deux jours par semaine, comme je l'avais initialement prévu. Les postes à mi-temps ont une extensibilité très forte dans le monde universitaire...

De plus, un autre délai impératif m'a été fixé pour finir un Diplôme d'études supérieures en linguistique informatique que j'avais entrepris depuis 1996. J'ai donc dû m'y consacrer de manière intensive de décembre à début mars. Parfois, je devais m'y consacrer pendant les heures ouvrables, notamment pour consulter les périodiques en bibliothèque. Ce mémoire a pris la plupart de mon temps au début de l'année.

Ensuite, comme j'avais aussi pris du retard sur le projet qui me sert de gagne-pain, j'ai dû travailler plus intensément les mois suivants pour combler mon retard. J'avais aussi quelques tâches qui concernaient d'autres modules Staf, et qui devaient être priorisées à causes de délais plus impératifs. Heureusement, après avoir validé mon stage, il ne me restera ensuite "que" le mémoire à réaliser.

Ce n'est qu'au mois de mai que j'ai établi un certain équilibre entre mon stage et mes autres tâches. Cet équilibre a été très difficile à respecter, mais le travail a quand même avancé de manière significative.

Il est très difficile, dans les faits, d'évaluer le nombre d'heures effectivement consacrées au stage. Toujours est-il que, quelles qu'en soient les raisons plus ou moins valables, il reste encore une bonne partie du travail à faire. Il est difficile d'évaluer combien de temps prendra encore la fin de la phase 6, et encore moins la phase 7. La phase 8, elle, devrait être relativement courte, si tout fonctionne correctement.

9. Conclusion

Ce stage se termine donc sur une réalisation inachevée. Il faudra tout de même que je finalise GENE afin de pouvoir enfin terminer ce diplôme Staf. C'est sans doute le point le plus frustrant. Je constate tout de même que d'autres tâches que j'ai dû réaliser, et notamment dans le cadre de ce diplôme, ont été réalisées avec succès. C'est une forme de consolation.

J'ose enfin espérer que les difficultés d'organisation me seront profitables. En effet, dès le mois d'octobre, j'aurai deux mandats à réaliser à l'université, avec deux équipes différentes et deux taux d'occupation différentes, sans compter une tâche d'enseignement dans le cadre de travaux pratiques. A moi donc de mieux m'organiser pour pouvoir mener de front ces tâches, terminer GENE, mener les expériences pour le mémoire et le rédiger!


Sébastien L'HAIRE.

Retour à la page travaux