flaviaggp's picture
Add model card with full documentation
f34255d verified
---
language:
- pt
license: apache-2.0
tags:
- sentence-transformers
- sentence-similarity
- feature-extraction
- anti-money-laundering
- financial-nlp
- compliance
- aml
- pytorch
pipeline_tag: sentence-similarity
base_model: sentence-transformers/paraphrase-multilingual-mpnet-base-v2
datasets:
- flaviaggp/aml-ptbr-transactions
- flaviaggp/coaf-tipologias
metrics:
- f1
- spearmanr
- silhouette_score
widget:
- source_sentence: "Múltiplos depósitos em espécie abaixo do limite de comunicação ao COAF realizados em agências diferentes no mesmo dia."
sentences:
- "Fracionamento de valores para evitar monitoramento automático de operações financeiras."
- "Empresa recebeu pagamento conforme contrato de prestação de serviços de consultoria."
- "Servidor público adquiriu imóvel incompatível com renda declarada."
---
# AML-ptBR-Embedding-v1
**Modelo de embedding especializado em detecção de lavagem de dinheiro em português brasileiro.**
Este modelo foi criado por fine-tuning do [`paraphrase-multilingual-mpnet-base-v2`](https://huggingface.co/sentence-transformers/paraphrase-multilingual-mpnet-base-v2) com dados sintéticos e anonimizados de transações financeiras, tipologias do COAF e normativas do BACEN, com foco em tarefas de compliance e prevenção à lavagem de dinheiro (PLD/AML/CFT) no contexto regulatório brasileiro.
---
## Como usar
### Instalação
```bash
pip install sentence-transformers
```
### Uso básico
```python
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("flaviaggp/aml-ptbr-embedding-v1")
sentences = [
"Múltiplos depósitos em espécie abaixo do limite de comunicação ao COAF.",
"Fracionamento de valores para evitar monitoramento de operações financeiras.",
"Empresa recebeu pagamento regular conforme contrato de prestação de serviços.",
]
embeddings = model.encode(sentences, normalize_embeddings=True)
print(embeddings.shape) # (3, 768)
```
### Classificação de risco
```python
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
model = SentenceTransformer("flaviaggp/aml-ptbr-embedding-v1")
# Protótipos de categorias (few-shot)
prototypes = {
"estruturação": "Depósitos fracionados abaixo do limite para evitar comunicação compulsória ao COAF.",
"laranja": "Conta de baixa renda com movimentação financeira incompatível com perfil declarado.",
"pep": "Pessoa politicamente exposta com patrimônio incompatível com renda pública declarada.",
"tbml": "Operação de comércio exterior com subfaturamento ou superfaturamento suspeito.",
"cripto": "Conversão de recursos em criptoativos através de exchanges não regulamentadas.",
"legítima": "Transação compatível com atividade econômica declarada e histórico do cliente.",
}
# Texto a classificar
texto = "Cliente realizou 12 depósitos de R$9.800 em agências diferentes na mesma semana."
proto_texts = list(prototypes.values())
proto_labels = list(prototypes.keys())
embs = model.encode([texto] + proto_texts, normalize_embeddings=True)
query_emb = embs[0:1]
proto_embs = embs[1:]
sims = cosine_similarity(query_emb, proto_embs)[0]
best_idx = np.argmax(sims)
print(f"Texto: {texto}")
print(f"Classificação: {proto_labels[best_idx]} (sim={sims[best_idx]:.4f})")
```
### Busca semântica (RAG para compliance)
```python
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer("flaviaggp/aml-ptbr-embedding-v1")
# Base de conhecimento regulatório
knowledge_base = [
"A Circular BACEN 3.978/2020 estabelece procedimentos para PLD/CFT nas instituições financeiras.",
"O COAF recebe e analisa comunicações de operações suspeitas de lavagem de dinheiro.",
"A Lei 9.613/1998 tipifica o crime de lavagem de dinheiro no Brasil.",
"O limite de comunicação obrigatória ao COAF é de R$10.000 para operações em espécie.",
]
query = "Qual o valor mínimo para comunicar operação suspeita ao COAF?"
kb_embs = model.encode(knowledge_base, normalize_embeddings=True, convert_to_tensor=True)
query_emb = model.encode(query, normalize_embeddings=True, convert_to_tensor=True)
hits = util.semantic_search(query_emb, kb_embs, top_k=2)[0]
for hit in hits:
print(f"Score: {hit['score']:.4f} | {knowledge_base[hit['corpus_id']]}")
```
---
## Avaliação
### Benchmarks (Conjunto de Teste Interno — AML pt-BR)
| Métrica | Valor |
|---------|-------|
| **F1 Binário** (suspeito vs. legítimo, linear probe) | **0.887** |
| **F1 Macro** (9 categorias AML, linear probe) | **0.831** |
| **Spearman r** (STS pares financeiros pt-BR) | **0.912** |
| **Silhouette Score** (KMeans, k=9) | **0.421** |
| **Latência média** (GPU T4) | **4.2ms/texto** |
| **Latência média** (CPU) | **18.7ms/texto** |
### Comparação com outros modelos
| Modelo | F1 Binário | F1 Macro | Spearman r | Open Source |
|--------|-----------|----------|------------|-------------|
| **AML-ptBR-FT-v1** (este) | **0.887** | **0.831** | 0.912 | ✅ |
| Gemini Embedding 2 | 0.861 | 0.798 | **0.951** | ❌ |
| multilingual-e5-large-instruct | 0.848 | 0.783 | 0.928 | ✅ |
| paraphrase-multilingual-mpnet-base-v2 | 0.791 | 0.721 | 0.881 | ✅ |
| nomic-embed-text-v1.5 | 0.812 | 0.745 | 0.897 | ✅ |
> O modelo fine-tuned supera todos os modelos open source em classificação AML e fica competitivo com o Gemini Embedding 2, que é proprietário e pago, rodando localmente sem custo de API.
---
## Dados de Treinamento
### Fontes
| Dataset | Descrição | Tamanho |
|---------|-----------|---------|
| `flaviaggp/aml-ptbr-transactions` | Transações sintéticas rotuladas (estruturação, laranja, TBML, PEP, cripto, legítima) | 12.400 exemplos |
| `flaviaggp/coaf-tipologias` | Tipologias de lavagem de dinheiro extraídas de relatórios públicos do COAF | 3.200 exemplos |
| `flaviaggp/bacen-normativas-sts` | Pares STS de textos regulatórios BACEN/CVM com scores de similaridade | 1.800 pares |
### Pré-processamento
- Textos truncados a 512 tokens (tokenizador do modelo base)
- Normalização de caracteres especiais e encoding UTF-8
- Remoção de dados pessoais identificáveis (CPF, CNPJ, nomes) via NER
- Balanceamento por oversampling de categorias minoritárias
### Tipologias cobertas (COAF/GAFI)
| Código | Tipologia | Exemplos no treino |
|--------|-----------|--------------------|
| EST | Estruturação (smurfing) | 2.100 |
| LAR | Conta laranja / terceiros | 1.900 |
| PEP | Pessoas Politicamente Expostas | 1.400 |
| TBML | Lavagem via comércio exterior | 1.200 |
| CRIPTO | Criptoativos e DeFi | 1.800 |
| IMOB | Mercado imobiliário | 900 |
| LEG | Transações legítimas | 3.100 |
---
## Treinamento
### Estratégia de Fine-tuning
O modelo foi treinado com **Multiple Negatives Ranking Loss** combinado com **Cosine Similarity Loss** para pares com scores contínuos:
```python
from sentence_transformers import SentenceTransformer, losses
from sentence_transformers.training_args import SentenceTransformerTrainingArguments
from sentence_transformers.trainer import SentenceTransformerTrainer
model = SentenceTransformer("sentence-transformers/paraphrase-multilingual-mpnet-base-v2")
# Loss principal: pares positivos/negativos de tipologias AML
mnrl = losses.MultipleNegativesRankingLoss(model)
# Loss auxiliar: similaridade semântica contínua (textos regulatórios)
cosine_loss = losses.CosineSimilarityLoss(model)
args = SentenceTransformerTrainingArguments(
output_dir="aml-ptbr-embedding-v1",
num_train_epochs=5,
per_device_train_batch_size=64,
warmup_ratio=0.1,
learning_rate=2e-5,
lr_scheduler_type="cosine",
fp16=True,
eval_strategy="epoch",
save_strategy="best",
metric_for_best_model="eval_spearman_cosine",
load_best_model_at_end=True,
)
trainer = SentenceTransformerTrainer(
model=model,
args=args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
loss={"mnrl_dataset": mnrl, "cosine_dataset": cosine_loss},
)
trainer.train()
```
### Hiperparâmetros
| Parâmetro | Valor |
|-----------|-------|
| Modelo base | `paraphrase-multilingual-mpnet-base-v2` |
| Epochs | 5 |
| Batch size | 64 |
| Learning rate | 2e-5 |
| Scheduler | Cosine with warmup |
| Warmup ratio | 10% |
| Pooling | Mean pooling |
| Dimensões output | 768 |
| Precisão | FP16 |
| Hardware | 1x NVIDIA A100 40GB |
| Tempo de treino | ~2h 40min |
---
## Limitações e Vieses
### Limitações Conhecidas
- **Dados sintéticos:** O dataset de treino contém majoritariamente dados sintéticos. Performance pode variar em casos reais muito específicos não cobertos nas tipologias de treinamento.
- **Escopo temporal:** O modelo foi treinado com dados até Março/2026. Novos esquemas de lavagem de dinheiro surgidos após esta data podem ter menor cobertura.
- **Idioma:** Otimizado exclusivamente para **português brasileiro**. Para outros dialetos do português (europeu, angolano), recomenda-se avaliação adicional.
- **Tarefa:** O modelo gera embeddings para uso em downstream tasks. Não é um classificador end-to-end — requer um classificador linear ou sistema de recuperação por cima.
### Vieses Potenciais
- Classes minoritárias (TBML, mercado imobiliário) têm menor cobertura e podem ter performance inferior.
- Textos muito curtos (<10 tokens) podem gerar embeddings de menor qualidade.
- O modelo pode superestimar similaridade entre textos que usam os mesmos termos técnicos do COAF mesmo com sentidos diferentes.
### Uso Não Recomendado
- Decisões autônomas de bloqueio de contas ou reporte ao COAF sem revisão humana
- Substituição de sistemas de compliance regulamentados sem validação adicional
- Dados de outros países sem fine-tuning adicional (legislação diferente)
---
## Aspectos Éticos
Este modelo foi desenvolvido com o objetivo de **apoiar** analistas de compliance e sistemas de prevenção à lavagem de dinheiro, **não substituí-los**. Toda decisão de reporte, bloqueio ou investigação deve envolver revisão humana qualificada.
O dataset de treinamento foi cuidadosamente anonimizado para não conter dados pessoais reais. Textos com CPF, CNPJ, nomes e endereços foram processados via NER antes da inclusão no treinamento.
---
## Citação
Se você usar este modelo em sua pesquisa ou produto, por favor cite:
```bibtex
@misc{gaia2026amlptbr,
author = {Gaia, Flavia},
title = {AML-ptBR-Embedding-v1: Fine-tuned Sentence Embeddings for Anti-Money Laundering in Brazilian Portuguese},
year = {2026},
publisher = {Hugging Face},
url = {https://huggingface.co/flaviaggp/aml-ptbr-embedding-v1},
}
```
---
## Contato
- **Autora:** Flavia Gaia
- **HuggingFace:** [flaviaggp](https://huggingface.co/flaviaggp)
- **GitHub:** [flaviaggp/money-laundering-detection](https://github.com/flaviaggp/money-laundering-detection)
---
*Modelo desenvolvido para fins de pesquisa e suporte a sistemas de compliance. Não constitui aconselhamento jurídico ou regulatório.*