Skip to content
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
## Release v0.9.0 - TBD

### Added

- Added possibility to train models on custom datasets, without generating synthetic data.
- Added Italian `SpamDetection` model.
- Added the `TextSummarization` model.

## Release v0.8.0 - March 26, 2026

### Added

- Added German, Spanish Guardrail model and German, Spanish Spam Detection model.
- Added German, Spanish `Guardrail` model and German, Spanish `SpamDetection` model.

### Changed

Expand Down
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
</p>

<p align="center">
<strong>Small Language Model Inference, Fine-Tuning and Observability. No GPU, no labeled data needed.</strong>
<strong>Small Language Model Inference, Fine-Tuning and Observability. No GPU, no labeled data needed.</strong>
</p>

---
Expand Down Expand Up @@ -61,21 +61,18 @@ Artifex changes that:

At this time, Artifex supports the following models:

| Task | Language(s) | Description | Default Model | How to use |
| Task | Available Languages | Description | Default Model | How to use |
|------|----------|-------------|---------------|------------|
| Guardrail | English | Flags unsafe, harmful, or off-topic messages. | [tanaos/tanaos-guardrail-v2](https://huggingface.co/tanaos/tanaos-guardrail-v2) | [Examples](https://docs.tanaos.com/artifex/guardrail/code-examples/)
| Guardrail | Spanish | Flags unsafe, harmful, or off-topic messages. | [tanaos/tanaos-guardrail-spanish](https://huggingface.co/tanaos/tanaos-guardrail-spanish) | [Examples](https://colab.research.google.com/#fileId=https%3A//huggingface.co/tanaos/tanaos-guardrail-spanish.ipynb) |
| Guardrail | German | Flags unsafe, harmful, or off-topic messages. | [tanaos/tanaos-guardrail-german](https://huggingface.co/tanaos/tanaos-guardrail-german) | [Examples](https://colab.research.google.com/#fileId=https%3A//huggingface.co/tanaos/tanaos-guardrail-german.ipynb) |
| Guardrail | English, German, Spanish | Flags unsafe, harmful, or off-topic messages. | [tanaos/tanaos-guardrail-v2](https://huggingface.co/tanaos/tanaos-guardrail-v2) (English version, see the page for the other languages) | [Examples](https://docs.tanaos.com/artifex/guardrail/code-examples/)
| Intent Classification | English | Classifies user messages into predefined intent categories. | [tanaos/tanaos-intent-classifier-v1](https://huggingface.co/tanaos/tanaos-intent-classifier-v1) | [Examples](https://docs.tanaos.com/artifex/intent-classifier/code-examples/)
| Reranker | English | Ranks a list of items or search results based on relevance to a query. | [cross-encoder/mmarco-mMiniLMv2-L12-H384-v1](https://huggingface.co/cross-encoder/mmarco-mMiniLMv2-L12-H384-v1) | [Examples](https://docs.tanaos.com/artifex/reranker/code-examples/)
| Sentiment Analysis | English | Determines the sentiment (positive, negative, neutral) of a given text. | [tanaos/tanaos-sentiment-analysis-v1](https://huggingface.co/tanaos/tanaos-sentiment-analysis-v1) | [Examples](https://docs.tanaos.com/artifex/sentiment-analysis/code-examples/)
| Emotion Detection | English | Identifies the emotion expressed in a given text. | [tanaos/tanaos-emotion-detection-v1](https://huggingface.co/tanaos/tanaos-emotion-detection-v1) | [Examples](https://docs.tanaos.com/artifex/emotion-detection/code-examples/)
| Named Entity Recognition | English | Detects and classifies named entities in text (e.g., persons, organizations, locations). | [tanaos/tanaos-NER-v1](https://huggingface.co/tanaos/tanaos-NER-v1) | [Examples](https://docs.tanaos.com/artifex/named-entity-recognition/code-examples/)
| Text Anonymization | English | Removes personally identifiable information (PII) from text. | [tanaos/tanaos-text-anonymizer-v1](https://huggingface.co/tanaos/tanaos-text-anonymizer-v1) | [Examples](https://docs.tanaos.com/artifex/text-anonymization/code-examples/)
| Spam Detection | English | Identifies whether a message is spam or not. | [tanaos/tanaos-spam-detection-v1](https://huggingface.co/tanaos/tanaos-spam-detection-v1) | [Examples](https://docs.tanaos.com/artifex/spam-detection/code-examples/)
| Spam Detection | Spanish | Identifies whether a message is spam or not. | [tanaos/tanaos-spam-detection-spanish](https://huggingface.co/tanaos/tanaos-spam-detection-spanish) | [Examples](https://colab.research.google.com/#fileId=https%3A//huggingface.co/tanaos/tanaos-spam-detection-spanish.ipynb) |
| Spam Detection | German | Identifies whether a message is spam or not. | [tanaos/tanaos-spam-detection-german](https://huggingface.co/tanaos/tanaos-spam-detection-german) | [Examples](https://colab.research.google.com/#fileId=https%3A//huggingface.co/tanaos/tanaos-spam-detection-german.ipynb) |
| Spam Detection | English, German, Spanish, Italian | Identifies whether a message is spam or not. | [tanaos/tanaos-spam-detection-v1](https://huggingface.co/tanaos/tanaos-spam-detection-v1) (English version, see the page for the other languages) | [Examples](https://docs.tanaos.com/artifex/spam-detection/code-examples/)
| Topic Classification | English | Classifies text into predefined topics. | [tanaos/tanaos-topic-classification-v1](https://huggingface.co/tanaos/tanaos-topic-classification-v1) | [Examples](https://docs.tanaos.com/artifex/topic-classification/code-examples/)
| Text Summarization | English | Rewrites text in a more concise way. | [tanaos/tanaos-text-summarization-v1](https://huggingface.co/tanaos/tanaos-text-summarization-v1) | [Examples](https://docs.tanaos.com/artifex/text-summarization/code-examples/)

Looking for models in other languages? Our [Enterprise License](#license-paid--enterprise-solutions) includes models in any language. Reach out at [info@tanaos.com](mailto:info@tanaos.com) for more details.

Expand Down
20 changes: 17 additions & 3 deletions artifex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
SpamDetection, TopicClassification
from .models.named_entity_recognition import NamedEntityRecognition, TextAnonymization
from .models.reranker import Reranker
from .models.text_summarization import TextSummarization
from .config import config
console.print(f"[green]✔ Initializing Artifex[/green]")

Expand Down Expand Up @@ -56,6 +57,7 @@ def __init__(self, api_key: Optional[str] = None):
self._text_anonymization = None
self._spam_detection = None
self._topic_classification = None
self._text_summarization = None

def text_classification(self) -> ClassificationModel:
"""
Expand Down Expand Up @@ -160,12 +162,12 @@ def text_anonymization(self) -> TextAnonymization:
return self._text_anonymization

def spam_detection(
self, language: Literal["english", "spanish", "german"] = "english"
self, language: Literal["english", "spanish", "german", "italian"] = "english"
) -> SpamDetection:
"""
Lazy loads the SpamDetection instance.
Args:
language (Literal["english", "spanish", "german"]): The language of the text data.
language (Literal["english", "spanish", "german", "italian"]): The language of the text data.
Returns:
SpamDetection: An instance of the SpamDetection class.
"""
Expand All @@ -187,4 +189,16 @@ def topic_classification(self) -> TopicClassification:
if self._topic_classification is None:
with console.status("Loading Topic Classification model..."):
self._topic_classification = TopicClassification(synthex=self._synthex_client)
return self._topic_classification
return self._topic_classification

def text_summarization(self) -> TextSummarization:
"""
Lazy loads the TextSummarization instance.
Returns:
TextSummarization: An instance of the TextSummarization class.
"""

if self._text_summarization is None:
with console.status("Loading Text Summarization model..."):
self._text_summarization = TextSummarization(synthex=self._synthex_client)
return self._text_summarization
6 changes: 6 additions & 0 deletions artifex/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,17 @@ def DEFAULT_SYNTHEX_DATASET_NAME(self) -> str:
NER_HF_BASE_MODEL: str = "tanaos/tanaos-NER-v1"
NER_TOKENIZER_MAX_LENGTH: int = 256
NER_TAGNAME_MAX_LENGTH: int = 25

# Text Summarization Model
TEXT_SUMMARIZATION_HF_BASE_MODEL: str = "tanaos/tanaos-text-summarization-v1"
TEXT_SUMMARIZATION_MAX_INPUT_LENGTH: int = 512
TEXT_SUMMARIZATION_MAX_TARGET_LENGTH: int = 128

# Spam Detection Models
SPAM_DETECTION_ENGLISH_HF_BASE_MODEL: str = "tanaos/tanaos-spam-detection-v1"
SPAM_DETECTION_SPANISH_HF_BASE_MODEL: str = "tanaos/tanaos-spam-detection-spanish"
SPAM_DETECTION_GERMAN_HF_BASE_MODEL: str = "tanaos/tanaos-spam-detection-german"
SPAM_DETECTION_ITALIAN_HF_BASE_MODEL: str = "tanaos/tanaos-spam-detection-italian"
SPAM_DETECTION_EVAL_DATASET: str = "hf://datasets/Deysi/spam-detection-dataset/data/train-00000-of-00001-daf190ce720b3dbb.parquet"

# Topic Classification Model
Expand Down
29 changes: 28 additions & 1 deletion artifex/core/_hf_patches.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from transformers import Trainer, TrainerState, TrainingArguments, TrainerCallback, TrainerControl
from transformers import Trainer, TrainerState, TrainingArguments, TrainerCallback, TrainerControl, \
Seq2SeqTrainer
from transformers.trainer_utils import TrainOutput
from typing import Any, Dict
from rich.progress import Progress, BarColumn, TextColumn, TimeElapsedColumn, TaskID
Expand Down Expand Up @@ -35,6 +36,32 @@ def silent_print(*a: Any, **k: Any) -> None:
return super().train(*args, **kwargs)
finally:
builtins.print = orig_print


class SilentSeq2SeqTrainer(Seq2SeqTrainer):
"""
A regular transformers.Seq2SeqTrainer which prevents the tedious final training summary
dictionary from being printed to the console.
"""

def train(self, *args: Any, **kwargs: Any) -> TrainOutput:
import builtins
orig_print = builtins.print

def silent_print(*a: Any, **k: Any) -> None:
if (
len(a) == 1
and isinstance(a[0], dict)
and "train_runtime" in a[0]
):
return
return orig_print(*a, **k)

builtins.print = silent_print
try:
return super().train(*args, **kwargs)
finally:
builtins.print = orig_print


class RichProgressCallback(TrainerCallback):
Expand Down
5 changes: 4 additions & 1 deletion artifex/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from .reranker import Reranker

from .text_summarization import TextSummarization

__all__ = [
"ClassificationModel",
"EmotionDetection",
Expand All @@ -18,5 +20,6 @@
"Reranker",
"SpamDetection",
"TopicClassification",
"Guardrail"
"Guardrail",
"TextSummarization"
]
Loading
Loading