fiscal-qa, une librairie d’extraction de paramètres OpenFisca dans des
textes légaux
This file will become your README and also the index of your documentation.
Utilisation
Installation
pip install fiscal_qa
Usage
[!!! API hypothétique !!!] L’usage attendu pourrait ressembler à :
localise(openfisca_id=..., document=...)
retourne la section du texte
qui contient la valeur au format (debut,fin)
(entier)
extract(openfisca_id=..., document=...)
retourne la valeur elle-même
au format valeur
(float)
localise_and_extract()
retourne les deux au format
(valeur, (debut,fin))
Historique du projet et problèmes rencontrés
Le projet a commencé avec l’objectif de créer une application
automatique qui puisse récupérer automatiquement des paramètres fiscaux,
en partant de son identifiant OpenFisca (par exemple
marche_travail.salaire_minimum.smic.smic_b_horaire
),
qui permet d’accéder à la fois à sa description (“Smic brut (horaire)”),
sa dernière valeur connue (11.27 au 1er janvier 2023) et au texte de loi
consolidé en vigueur qui contient la valeur (décret n° 2022-1608 du 22
décembre 2022). Un second objectif a plus tard émergé, largement
indépendant du premier : celui de localiser le passage précis qui
contien la nouvelle valeur, sous la forme d’un couple (début, fin)
, à
servir dans des interfaces graphiques (surligner le passage du texte qui
met en place tel paramètre fiscal).
Par la suite, il serait possible de repérer tout changement de tels textes de loi, et donc de mener une veille permanente sur les paramètres fiscaux concernés.
Afin de répondre à nos deux objectifs, nous essayons d’utiliser un mélange de modèles de traitement du langage basés sur des réseaux de neurones et de méthodes plus déterministes (règles dichotomiques, expressions régulières, etc.).
Les contraintes relevées à ce jour : - les textes de lois peuvent être très long, il faut donc soit que le modèle de langue accepte des entrées longues, soit qu’on soit en mesure de localiser par des heuristiques la situation du paramètre fiscal dans le texte - la loi modificatrice d’un paramètre fiscal, référencée dans OpenFisca, peut modifier plusieurs textes ; il faut donc identifier (automatiquement ou manuellement) le texte précis qui contient la nouvelle valeur ; la concaténation des textes augmente encore la longueur du texte à traiter - le modèle de langue utilisé doit comprendre le français - le modèle de langue utilisé doit comprendre le vocabulaire juridique - le modèle de langue utilisé doit avoir des conditions de réutilisation adaptées (idéalement, être OpenSource) - la valeur retournée est une valeur numérique, il faudrait donc soit que le modèle de langue puisse être contraint à générer des valeurs numériques, soit que la valeur non numériques (par exenple “5000 euros” ou “43,2%”) soit ultérieurement convertie en valeur numérique - il existe des paramètres fiscaux complexes, comme les barêmes d’imposition sur le revenu [exclus en première approche] - les valeurs peuvent être contenues dans des tableaux, et peuvent donc nécessiter des modèles adaptés - le temps de calcul n’est pas une grosse contrainte, mais des modèles rapides sont néanmoins préférables
Nous avons à disposition dans OpenFisca des données historiques qui peuvent servir pour l’éventuel entraînement “de perfection” (finetuning) du modèle, mais qui ne comportent pas la localisation précise du passage dans le texte de loi. Ces exemples peuvent également servir pour les invites de génération (ou prompts) afin d’orienter la génération de réponses de meilleure qualité.
Les pistes explorées : - modèle de langue seul utilisé pour la
prédiction de la valeur uniquement (sans localisatio, sans
post-traitement) [résultats décevants d’env. 5% d’extraction avec les
modèles ci-dessous] - idem avec post-traitement artisanal sommaire
(ex: suppression des unités monétaires, conversion des pourcentages)
[même performence basse] - contrainte sur la génération avec les
bilbiothèque transformers
et lmql
[impossible à ce jour de
générer des tokens numériques uniquement]
Modèles envisagés et testés
Légende :
- - : donnée non pertinente
- 🤗 : lien HuggingFace
- 🇫🇷 : compréhension du français
- ↔️ : longueut maximale d’une séquence en entrée
- ⚙️ : statut d’implémentation ( ✅ : implémenté, ⌛ : en cours, ❌ : non implémenté)
- 📜 : licence (🤔 : incertain)
Contribuer
Installation de la version de développement
Ce dépôt utilise poetry
pour la gestion
des librairies et dvc
pour le versionnement des
données et des modèles de traitement du language naturel (NLP).
# Poetry installation
# (DVC is installed automatically as a Python library as part of the environment)
curl -sSL https://install.python-poetry.org | python3 -
export PATH="/path/to/poetry/commands/as/provided/in/poetry/installation/logs:$PATH"
Pour installer le code source de la librarie en local, exécutez les commandes suivantes.
# make sure to clone the repository on a disk with enough storage
# For instance, if llama7b is selected at model.id in params.yaml,
# as llama7b has a size of 4 * 7GB = 28GB (each parameter needs 32b=4B)
# then one needs at least 28GB of disk storage just for storing the weights
# You can go visit the model's webpage on HuggingFace to check.
git clone https://git.leximpact.dev/leximpact/fiscal-qa.git
cd fiscal-qa
poetry install # this also installs DVC in the Python environment
Pour vérifier que Poetry a bien installé DVC :
poetry run dvc --version
L’installation par défaut comprend un modèle de langue très peu
pertinent (paramètre model.id
dans le fichier params.yaml
),
caractérisé par sa petite taille. En effet, l’installation de tout
modèle raisonablement performant nécessite un grand espace disque, afin
de stocker le(s) modèle(s) de langue en cours d’utilisation. Par
exemple, on peut estimer que le modèle “huggyllama/llama-7b” nécessite
au moins 4 \text{ o} \times 7.10^9 = 28Go d’espace libre (c’est un
modèle 7 millions de paramètres et chaque paramètre est un nombre
flottant à 32b=4o). Vous pouvez visiter le site https://huggingface.co/
pour retrouver la taille des fichiers à l’onglet “Files and versions”.
Les modèles et données sont situées sur un serveur distant connu par DVC
sous le nom de sscloud
. Il est possible de récupérer les fichiers via
la commande :
poetry run dvc pull
Les données sont alors téléchargées dans le répertoire data/
et les
modèles dans le répertoire models/
.
On peut alors reproduire la chaîne de traitement avec l’instruction :
poetry run dvc repro
Structure
Les dossiers suivants peuvent être modifiés manuellement : -
notebooks/
contient le code de la librairie, sous forme de cahiers
Jupyter déclarés via la librairie nbdev
; le
cahier index.ipynb
génère la présente page - explore/
est un dossier
contenant des cahiers exploratoires sur de nouvelles fonctionalités et
de nouveaux modèles
Les dossiers suivants sont généralement générés de façon automatique : -
fiscal_qa/
contient la librairie proprement dite générée
automatiquement par nbdev
- data/
contient les données, brutes ou
traitées ; elles sont sauvegardées automatiquement par DVC - models/
contient le modèle en utilisation courante ; les modèles sont
généralement importés programatiquement, et supprimés après usage ; ils
sont sauvegardés automatiquement par DVC
Exécuter la chaîne de traitement, exécuter une nouvelle expérience
Les différentes étapes de la chaîne de traitement qui définit une
expérience sont décrites dans dvc.yaml
. Les paramètres des expériences
sont décrits dans le fichier params.yaml
.
Une nouvelle combinaison de paramètres dans params.yaml
(sans
changement du code de la librairie) permet de générer une nouvelle
expérience via l’instruction :
poetry run dvc repro # only runs the steps that depends on a new model or on new data
poetry run dvc repro -f # forces execution (useful when only the code has changed)
poetry run dvc repro [step] # run only step <step>
Alternativement, une expérience peut-être générée “à la volée” en modifiant un ou plusieurs paramètres en ligne de commande:
poetry run dvc exp run --set-param <param>=<value>
L’historique des expériences est consultable via :
dvc exp show
Dans les deux cas, DVC soumet automatiquement la modification des
données et du modèle au serveur distant ; données et modèle sont ignorés
par Git, qui soumet un hash au format <file>.dvc
.
git commit -m "new experiment"
poetry run dvc push -r ssplab-s3 # this requires credentials to the remote
Exactement de la même façon, on peut récupérer des changements soumis par des tiers:
git pull origin # has to come first, retreives the hash files
dvc pull ssplab # retrieves the corresponding true files
Modifier la structure de la chaîne de traîtement
Changer la chaîne de traitement nécessite de changer le fichier
dvc.yaml
. Les paramètres amenés à être optimisés sont spécifiés dans
params.yaml
.
L’étape du tratiement fait appel à une instruction bash précisée dans le
paramètre cmd
de dvc.yaml
. Les dépendences sont décrites par le
paramètre deps
. Jusqu’à présent, les instructions bash sont générées
en fin des cahiers Jupyter du dossier notebooks
. Elles sont déclarées
au niveau de l’environnement à la fin du fichier pyproject.toml
à la
section [tool.poetry.scripts]
.
Prochaines étapes
- supprimer les archives
- relire le tableau des modèles et mettre à jour si nécessaire
-
relire les notebooks du dossieur
explore
- clarifier dans le readme la distinction entre utilisation et contribution
-
fusionner les branches de travail dans
main
- tester les paramètres GPU (sur le SSP Lab du coup)
- remettre les timings
- statistiques sur les résultats (temps moyen par prédiction ; taux de succès, etc.)
- remettre la génération contrainte
- tests de la génération contrainte
- nettoyer le code
- make DVC remote work again
- faire que dvc exp ajoute bien des données au exp log
- remettre le batching
- option pour exemple “adapté” à chaque extraction
- Tester l’installation en local
- Tester l’installation sur le cloud
- enlever self. pour les errors, values, etc.
Possible improvements
- étendre la couverture des paires (paramètres ; texte de loi) ; actuellement seuls les cas les plus simples (1 paramètre <=> 1 texte Légifrance) sont utilisés
- add random seed in parameters so that results can be reproduced
- check whether updates are avaiable for models on Huggingface ; download model if new version is available
-
in
load_pretrained...()
, allow for the model name to be passed as a parameter to the bash call - use the batch treatment from huggingface
- compute execution time per run
- remove legal inputs greater than model admissible length
- use library to convert all number-like strings to numbers
- use contraints on the text generator (when this becomes more widely available)
- track time spent / memory use during evaluation
- it could be an idea to make all the dependencies apparent in the bash commands, instead of fetching them in params in the middle of the function calls
- ajouter des tests sur chaque nouveau modèle pour vérifier ses propriétés: cf. vigogne et llama exploration notebooks
- updates of the reference file (refeences-legifrance.json) may challenge the current organisation of the pipeline
- maintain updated model info at download time
- save preprocessed docs
- modular way to postprocess outputs
- control verbosity
- control random seed for reproducibility
- removing HTML [needed? possibly to limit the number of tokens needed]
- accelerate with CUDA
- accelerate with MPS
- instor multiple generations + majority voting ?
- disk space use (over the entier DVC pipeline)
- deal with model max length (incl. truncate too long inputs ?)
- add truncation to preprocessing
- check memory and disk space usage with new object-oriented structure
- enchaîner un modèle de discrimination à une génération de plusieurs valeurs
- enchaîner un modèle de conversion sous contrainte à un modèle d’extraction libre
- remove examples from the token count
- mismatch between search+doc and parameter+text and context
- verify that acceleration device is correctly noted in log
- check back memory use and disk use