--- 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.*