File size: 4,740 Bytes
0dd9c73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f0d843a
 
 
 
0dd9c73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
---
language: fr
license: mit
library_name: onnx
tags:
  - token-classification
  - pii
  - anonymization
  - french
  - camembert
base_model: almanach/camembert-base
---

# Noirci — détection de données personnelles en français

Modèle de reconnaissance d'entités entraîné pour **pseudonymiser de la
correspondance professionnelle française** avant de l'envoyer à un LLM.
Exporté en ONNX quantifié int8 : 186 Mo, tourne sur CPU.

Développé par **[5000.dev](https://5000.dev)**.

Le moteur complet et le protocole de mesure sont publiés avec le benchmark :
[5000dev/noirci-bench](https://huggingface.co/datasets/5000dev/noirci-bench).

## La métrique compte autant que le modèle

Une entité n'est protégée que si **100 % de ses caractères significatifs
sont masqués**. Masquer « Jean » dans « Jean Dupont » est compté comme une
fuite, pas comme un demi-succès : le nom de famille est parti chez le
fournisseur du LLM. Les scores F1 par token, usuels dans la littérature,
récompensent ces demi-succès et surestiment fortement la protection réelle.

On mesure donc deux choses séparément : le **taux de fuite** (l'entité
a-t-elle été entièrement masquée) et le **taux de sur-masquage** (combien de
texte inutile a été masqué au passage).

## Résultats

Sur de la correspondance professionnelle française authentique, annotée à la
main. Le modèle n'est qu'une couche du pipeline complet ; les chiffres
ci-dessous sont ceux du pipeline `lite2`.

| Jeu | Documents | Entités | Fuite | Sur-masquage |
|---|---|---|---|---|
| Validation (tenu à l'écart) | 72 | 555 | 3,96 % | 17,7 % |
| Entraînement | 407 | 3 576 | 3,30 % | 11,2 % |
| Aveugle (annoté avant exécution) | 7 | 55 | 5,45 % | 8,0 % |

Par type sur le jeu le plus large : PERSON 0,00 %, URL 0,60 %, CITY 1,47 %,
ADDRESS 1,74 %, PHONE 2,59 %, DATE 3,58 %, AMOUNT 4,58 %, COMPANY 5,70 %.
Les identifiants à somme de contrôle (SIREN, SIRET, TVA, IBAN, NIR) sont à
0,00 % : ils sont traités par la couche déterministe, pas par le modèle.

## Ce que le modèle a appris, et pourquoi

Le corpus d'entraînement mélange du synthétique métier (juridique, compta,
RH, immobilier, administratif), du WikiNER français, et de la **prose réelle
à valeurs substituées** : de vrais documents dont chaque entité a été
remplacée par une autre valeur réelle du même type, tirée de sources
publiques (BODACC, INSEE). La structure vient du réel, aucune donnée client
ne subsiste.

Un point non évident : la **forme de surface** des sociétés a été réalignée
sur la distribution observée. Les pools BODACC et SIRENE stockent les
raisons sociales en capitales, ce qui donnait un corpus à 65 % de
majuscules contre 17 % dans la vraie correspondance. Le modèle apprenait
qu'« une société, c'est un mot en capitales » et ratait 40 % des marques
écrites normalement, en simple capitale initiale. Corriger cette seule
distribution a fait passer les sociétés de 9,7 % à 6,7 % de fuite.

## Contenu du dépôt

| Fichier | |
|---|---|
| `model.safetensors` | les poids en float32, pour réentraîner ou réexporter |
| `onnx/model_int8.onnx` | l'export quantifié, 186 Mo, tourne sur processeur |
| `tokenizer.json` | **sans troncature**. Le fichier sauvé après entraînement en embarquait une, silencieuse, à 192 tokens : la fin de tout document long n'était jamais analysée. Si vous repartez d'un autre export, vérifiez ce point. |

## Utilisation

Le modèle seul n'est pas suffisant. Il est conçu comme une couche d'un
pipeline qui comprend aussi des regex à checksums, des gazetteers (communes
INSEE, dénominations SIRENE) et une passe de propagation document entier.
Voir le dépôt GitHub.

```python
from bench.detect.run import DETECTORS
spans = DETECTORS["lite2"]("Bonjour, je suis Claire Baudry de la Verrerie Delaunay.")
```

## Limites

- **Français uniquement.** Quelques formats anglo-saxons sont couverts parce
  qu'ils apparaissent dans de la correspondance française, mais ce n'est pas
  un modèle multilingue.
- **Le sur-masquage est réel**, entre 8 et 15 %. Environ un mot masqué sur
  sept l'est inutilement.
- **Les benchmarks synthétiques sont saturés** (0,04 % de fuite) et ne
  discriminent plus rien. Ne jugez pas ce modèle dessus.
- **Le périmètre exclut les plateformes grand public** (Zoom, Excel, Stripe,
  Figma). Ce sont des noms de produits, pas des données personnelles, et les
  masquer dégrade la réponse du LLM sans rien protéger.

## Licence et attributions

MIT. Modèle de base : `almanach/camembert-base` (MIT). Données
d'entraînement dérivées de WikiNER (CC-BY), BODACC et INSEE SIRENE (Licence
Ouverte), Wikidata (CC0). Voir `NOTICE` dans le dépôt.