wtpsplit

repository·main·Indexed 23 days ago

https://github.com/segment-any-text/wtpsplit

A robust library for segmenting text into sentences, paragraphs, or other semantic units, supporting over 85 languages. It provides access to state-of-the-art SaT (Segment Any Text) models and legacy WtP models, with support for GPU, TPU, and ONNX acceleration. Key features include length-constrained segmentation using Viterbi or greedy algorithms, domain adaptation via LoRA, and integration with HuggingFace Transformers.

Tokens
6.9K
Snippets
18
Records
26
Agent score
80%

What's inside wtpsplit

  1. Use SaT models for different tasks

    main

    Choose a model based on your requirements:

    • General Tasks: Use -sm models (e.g., sat-3l-sm).
    • Speed/Efficiency: Use 3-layer models (sat-3l, sat-3l-sm).
    • High Accuracy: Use 12-layer models (sat-12l, sat-12l-sm).
    • Domain Adaptation: Use LoRA modules by providing style_or_domain and language arguments to the SaT constructor.
  2. Configure length-constrained segmentation in wtpsplit

    main

    When max_length is set, wtpsplit uses length-constrained segmentation. In this mode, the threshold parameter is ignored; instead, the algorithm uses raw model probabilities combined with a prior probability distribution to find optimal split points. This allows you to balance the model's boundary predictions with your specific length preferences.

    To use this, pass max_length to the split method. You can also specify a prior_type and prior_kwargs to control how much the algorithm prefers certain segment lengths.

    from wtpsplit import SaT
    
    sat = SaT("sat-3l-sm")
    
    # Basic length limiting (max 100 chars)
    segments = sat.split(text, max_length=100)
    
    # Both min and max constraints
    segments = sat.split(text, min_length=20, max_length=100)
  3. Choose the right WtP model

    main

    Select a model based on your performance and accuracy requirements:

    • Speed-sensitive applications: Use wtp-bert-mini.
    • High accuracy: Use wtp-canine-s-12l.
    • Balanced tradeoff: Use *-no-adapters models (e.g., wtp-canine-s-12l-no-adapters).
    • Avoid: wtp-bert-tiny is generally not recommended.
    ModelEnglish ScoreMultilingual ScoreNotes
    wtp-bert-mini91.884.3Recommended for speed
    wtp-canine-s-12l94.787.9High accuracy
    *-no-adaptersVariesVariesGood speed/performance tradeoff
  4. Choose a prior function for length constraints

    main

    The prior_type determines how the algorithm prefers segment lengths. Use the following guide to choose the best one for your task:

    PriorRecommendationBest For
    uniformDefaultJust enforce max_length, let the model decide split points
    gaussian⭐ RecommendedPrefer segments around a specific target_length (intuitive)
    lognormalAdvancedRight-skewed preference (more tolerant of longer segments)
    clipped_polynomialSpecial casesWhen segments MUST be very close to a target length

    Prior Configuration Details

    All priors support an optional lang_code in prior_kwargs to use language-aware defaults (e.g., "zh", "de", "en").

    1. Uniform: All lengths are equally good up to max_length. Hard cutoff at the limit.
    2. Gaussian: Symmetric bell curve. Requires target_length and spread. Best for embedding models (e.g., targeting 512 chars).
    3. Clipped Polynomial: A parabola that clips to zero at ±spread from target_length. More aggressive enforcement than Gaussian.
    4. Log-Normal: Asymmetric/Right-skewed. More tolerant of longer segments than shorter ones.
    # Prefer ~50 character segments using Gaussian prior
    segments = sat.split(
        text,
        max_length=100,
        prior_type="gaussian",
        prior_kwargs={"target_length": 50, "spread": 15}
    )
  5. Adapt SaT to your own corpus via LoRA

    main

    You can adapt SaT to a specific corpus using LoRA with as few as 10-100 segmented training sentences.

    1. Setup Environment

    Clone the repository and install the required dependencies, including the specific adapters version:

    git clone https://github.com/segment-any-text/wtpsplit
    cd wtpsplit
    pip install -r requirements.txt
    pip install adapters==0.2.1 --no-dependencies

    2. Prepare Training Data

    Create a .pth file containing your training data. The data must be structured as a nested dictionary. Important: Individual sentences must not contain newline characters (\n).

    import torch
    
    torch.save(
        {
            "language_code": {
                "sentence": {
                    "dummy-dataset": {
                        "meta": {
                            "train_data": ["train sentence 1", "train sentence 2"],
                        },
                        "data": [
                            "test sentence 1",
                            "test sentence 2",
                        ]
                    }
                }
            }
        },
        "dummy-dataset.pth"
    )

    3. Configure and Train

    Create a configuration JSON file (e.g., configs/lora/lora_dummy_config.json) specifying the model_name_or_path, output_dir, and text_path (the path to your .pth file).

    Run the training script:

    python3 wtpsplit/train/train_lora.py configs/lora/lora_dummy_config.json

    4. Inference with Adapted Model

    Load the trained adapter using the lora_path argument in the SaT constructor:

    sat_lora_adapted = SaT("model-used", lora_path="dummy_lora_path")
    sat_lora_adapted.split("Some domains-specific or styled text")
  6. Load SaT models in HuggingFace Transformers

    main

    SaT models can be integrated into the HuggingFace transformers ecosystem. You must import wtpsplit.models to register the custom models before loading them via AutoModelForTokenClassification.

    # import library to register the custom models 
    import wtpsplit.models
    from transformers import AutoModelForTokenClassification
    
    model = AutoModelForTokenClassification.from_pretrained("segment-any-text/sat-3l-sm") # or some other model name; see https://huggingface.co/segment-any-text
  7. Enable ONNX inference for speedup

    main

    You can enable ONNX inference for wtp-bert-* models to achieve faster performance on GPU. This requires onnxruntime and onnxruntime-gpu to be installed.

    Note: wtp-canine-* models are currently not supported with ONNX due to complex pooling operations. This feature is not compatible with Python 3.7.

  8. Adapt SaT models using LoRA

    main

    SaT (Segment Any Text) can be domain- and style-adapted using LoRA (Low-Rank Adaptation). This allows for strong adaptation to specific languages, domains (like legal documents), or styles (like tweets or ASR transcriptions).

    To use a pre-trained LoRA module, you must provide both the lang_code and the style_or_domain. Available modules can be found in the <model_repository>/loras folder.

    Note: When performing inference, ensure you use the same model variant (e.g., sat-12l) that was used during training, as adapters are not cross-compatible between different model architectures.

    # requires both lang_code and style_or_domain
    # for available ones, check the <model_repository>/loras folder
    sat_lora = SaT("sat-3l", style_or_domain="ud", language="en")
    sat_lora.split("Hello this is a test But this is different now Now the next one starts looool")
    
    # now for a highly distinct domain
    sat_lora_distinct = SaT("sat-12l", style_or_domain="code-switching", language="es-en")
    sat_lora_distinct.split("in the morning over there cada vez que yo decía algo él me decía algo")
  9. Adapt segmentation to specific styles or corpora

    main

    WtP supports adapting to styles like Universal Dependencies (UD), OPUS100, or Ersatz via punctuation or threshold adaptation.

    Punctuation Adaptation

    Requires a lang_code. You can specify a style and optionally a threshold.

    wtp.split(text, lang_code="en", style="ud")
    # Or with a custom threshold
    wtp.split(text, lang_code="en", style="ud", threshold=0.7)

    Threshold Adaptation

    You can retrieve the default threshold for a specific language and style using get_threshold and then apply it manually.

    # Get default threshold
    threshold = wtp.get_threshold("en", "ud")
    
    # Use it in split
    wtp.split(text, threshold=threshold)
  10. Adapt WtP to your own corpus

    main

    You can adapt WtP to a custom dataset using the adapt.py script.

    1. Prepare Data: Create a .pth file containing your training and test data in the expected nested dictionary format (Language -> Task -> Dataset -> Data).
    2. Run Adaptation: Use the wtpsplit/evaluation/adapt.py script.
    3. Load Mixture: Use skops to load the generated .skops mixture file into the WtP constructor.

    Example Workflow:

    # 1. Create dummy data
    import torch
    torch.save({
        "en": {
            "sentence": {
                "my-dataset": {
                    "meta": {"train_data": ["train sentence 1"]},
                    "data": ["test sentence 1"]
                }
            }
        }
    }, "dummy-dataset.pth")
    
    # 2. Run adaptation via CLI
    # python3 wtpsplit/evaluation/adapt.py --model_path=benjamin/wtp-bert-mini --eval_data_path dummy-dataset.pth --include_langs=en
    
    # 3. Load and use the mixture
    import skops.io as sio
    from wtpsplit import WtP
    
    wtp = WtP(
        "wtp-bert-mini",
        mixtures=sio.load(
            "path/to/mixture.skops",
            ["numpy.float32", "numpy.float64", "sklearn.linear_model._logistic.LogisticRegression"],
        ),
    )
    wtp.split("your text here", lang_code="en", style="my-dataset")
  11. Enable ONNX inference for faster performance

    main

    You can enable ONNX Runtime providers to achieve up to 50% faster inference compared to standard PyTorch. Pass the ort_providers list to the SaT constructor.

    Example using CUDA and CPU providers:

    from wtpsplit import SaT
    
    sat = SaT("sat-3l-sm", ort_providers=["CUDAExecutionProvider", "CPUExecutionProvider"])