Live demo — the parsley sentence segmenter +
tokenizer running in your browser · lexide on crates.io
There are two projects here, one is models for tagging sentences with POS labels and other info, the other is for converting audio input to a sequence of phonemes.
Fine-tuning Gemma 3 for multilingual part-of-speech tagging, lemmatization, and dependency parsing.
This repository contains the training code, the training data, and a REX library that can be used to actually use the model with a convenient API.
Download the models on Huggingface!
This project fine-tunes Google's Gemma 3 1B model to perform linguistic analysis across 7 languages:
The model learns to analyze sentences and output structured linguistic information including POS tags, lemmas, and syntactic dependencies.
Start job
sky start lexide
sky launch -c lexide --secret HF_TOKEN --secret WANDB_API_KEY sky.yaml
# Clone repository
git clone <repo-url>
cd lexide
# Install uv package manager
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync
# Pull data files (requires Git LFS)
git lfs pull
# Login to Hugging Face (for Gemma model access)
huggingface-cli login
# Start training
./launch_training.sh
# Test the latest checkpoint
uv run python test_checkpoint.py
# Interactive inference
uv run python inference_example.py
Given an input sentence, the model outputs linguistic analysis in this format:
Input:
Language: English
Sentence: I don't have them.
Task: Analyze tokens (idx,token,ws,POS,lemma,dep,head)
Output:
Here's the token analysis:
1 I none PRON I nsubj 4
2 do none AUX do aux 4
3 n't none PART not advmod 4
4 have none VERB have ROOT 0
5 them none PRON they obj 4
6 . none PUNCT . punct 4
</analysis>
The output format is tab-separated with columns: index, token, whitespace (none/_ for space), POS tag, lemma, dependency label, and head index.
lexide/
├── train/
│ ├── data/ # Training data (JSONL format)
│ │ ├── cleaned_eng.jsonl # English samples
│ │ ├── cleaned_deu.jsonl # German samples
│ │ ├── cleaned_fra.jsonl # French samples
│ │ ├── cleaned_ita.jsonl # Italian samples
│ │ ├── cleaned_kor.jsonl # Korean samples
│ │ ├── cleaned_por.jsonl # Portuguese samples
│ │ └── cleaned_spa.jsonl # Spanish samples
│ ├── src/
│ │ ├── data_loader.py # Data loading and preprocessing
│ │ ├── train.py # Main training script
│ │ ├── inference.py # Inference utilities
│ │ └── evaluate.py # Model evaluation
│ ├── launch_training.sh # Training launch script
│ ├── main.py # Training entry point
│ ├── inference_example.py # Interactive inference
│ ├── test_checkpoint.py # Quick testing script
│ └── sky.yaml # Skypilot configuration
├── lexide/ # Rust library for linguistic analysis
└── modal/ # Modal deployment scripts
Edit config.yaml to adjust training parameters:
model:
name: "google/gemma-3-1b-it" # Model variant
use_4bit: false # Quantization settings
training:
batch_size: 8 # Adjust based on GPU memory
learning_rate: 2e-4
num_epochs: 3
lora:
r: 16 # LoRA rank
alpha: 32 # LoRA scaling
A model that listens to speech and writes out the phonemes it hears, in IPA. The goal is transcribing what was actually said rather than what a dictionary says the words should sound like — so a learner can compare their pronunciation against a native target, sound by sound.
Training data is speech paired with phoneme labels in 11 languages (English, French, German, Spanish, Italian, Portuguese, Russian, Hindi, Japanese, Thai, Mandarin), drawn from FLEURS, Tatoeba, TTS, Pimsleur audio, and film clips whose subtitles were verified verbatim against an independent transcript. Labels come from a patched espeak-ng for the European languages and from real G2P backends where espeak isn't good enough (Open JTalk for Japanese, g2pM for Mandarin, TLTK for Thai, a schwa-deletion classifier for Hindi). A set of audits filters out clips whose audio and label don't match (Whisper re-transcription, an LLM language filter, acoustic measurement), and an "acoustic narrowing" pass moves labels from dictionary form toward what the speaker really produced (e.g. nasalized vowels, American English flapping) by measuring the signal itself.
pronunciation/
├── data/ # Downloaders + per-language audio, manifests, labels
├── train/ # Model, dataset, training loop, data-quality sidecars
├── espeak_audit/ # Acoustic measurement + label narrowing (Modal + parselmouth)
├── vad_compare/ # Rust voice-activity-detection tool
└── inference/ # Run the model on your own audio
138 commits
Python
64.7%
Rust
30.8%
JavaScript
1.9%
Shell
1.8%
Live demo — the parsley sentence segmenter +
tokenizer running in your browser · lexide on crates.io
There are two projects here, one is models for tagging sentences with POS labels and other info, the other is for converting audio input to a sequence of phonemes.
Fine-tuning Gemma 3 for multilingual part-of-speech tagging, lemmatization, and dependency parsing.
This repository contains the training code, the training data, and a REX library that can be used to actually use the model with a convenient API.
Download the models on Huggingface!
This project fine-tunes Google's Gemma 3 1B model to perform linguistic analysis across 7 languages:
The model learns to analyze sentences and output structured linguistic information including POS tags, lemmas, and syntactic dependencies.
Start job
sky start lexide
sky launch -c lexide --secret HF_TOKEN --secret WANDB_API_KEY sky.yaml
# Clone repository
git clone <repo-url>
cd lexide
# Install uv package manager
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install dependencies
uv sync
# Pull data files (requires Git LFS)
git lfs pull
# Login to Hugging Face (for Gemma model access)
huggingface-cli login
# Start training
./launch_training.sh
# Test the latest checkpoint
uv run python test_checkpoint.py
# Interactive inference
uv run python inference_example.py
Given an input sentence, the model outputs linguistic analysis in this format:
Input:
Language: English
Sentence: I don't have them.
Task: Analyze tokens (idx,token,ws,POS,lemma,dep,head)
Output:
Here's the token analysis:
1 I none PRON I nsubj 4
2 do none AUX do aux 4
3 n't none PART not advmod 4
4 have none VERB have ROOT 0
5 them none PRON they obj 4
6 . none PUNCT . punct 4
</analysis>
The output format is tab-separated with columns: index, token, whitespace (none/_ for space), POS tag, lemma, dependency label, and head index.
lexide/
├── train/
│ ├── data/ # Training data (JSONL format)
│ │ ├── cleaned_eng.jsonl # English samples
│ │ ├── cleaned_deu.jsonl # German samples
│ │ ├── cleaned_fra.jsonl # French samples
│ │ ├── cleaned_ita.jsonl # Italian samples
│ │ ├── cleaned_kor.jsonl # Korean samples
│ │ ├── cleaned_por.jsonl # Portuguese samples
│ │ └── cleaned_spa.jsonl # Spanish samples
│ ├── src/
│ │ ├── data_loader.py # Data loading and preprocessing
│ │ ├── train.py # Main training script
│ │ ├── inference.py # Inference utilities
│ │ └── evaluate.py # Model evaluation
│ ├── launch_training.sh # Training launch script
│ ├── main.py # Training entry point
│ ├── inference_example.py # Interactive inference
│ ├── test_checkpoint.py # Quick testing script
│ └── sky.yaml # Skypilot configuration
├── lexide/ # Rust library for linguistic analysis
└── modal/ # Modal deployment scripts
Edit config.yaml to adjust training parameters:
model:
name: "google/gemma-3-1b-it" # Model variant
use_4bit: false # Quantization settings
training:
batch_size: 8 # Adjust based on GPU memory
learning_rate: 2e-4
num_epochs: 3
lora:
r: 16 # LoRA rank
alpha: 32 # LoRA scaling
A model that listens to speech and writes out the phonemes it hears, in IPA. The goal is transcribing what was actually said rather than what a dictionary says the words should sound like — so a learner can compare their pronunciation against a native target, sound by sound.
Training data is speech paired with phoneme labels in 11 languages (English, French, German, Spanish, Italian, Portuguese, Russian, Hindi, Japanese, Thai, Mandarin), drawn from FLEURS, Tatoeba, TTS, Pimsleur audio, and film clips whose subtitles were verified verbatim against an independent transcript. Labels come from a patched espeak-ng for the European languages and from real G2P backends where espeak isn't good enough (Open JTalk for Japanese, g2pM for Mandarin, TLTK for Thai, a schwa-deletion classifier for Hindi). A set of audits filters out clips whose audio and label don't match (Whisper re-transcription, an LLM language filter, acoustic measurement), and an "acoustic narrowing" pass moves labels from dictionary form toward what the speaker really produced (e.g. nasalized vowels, American English flapping) by measuring the signal itself.
pronunciation/
├── data/ # Downloaders + per-language audio, manifests, labels
├── train/ # Model, dataset, training loop, data-quality sidecars
├── espeak_audit/ # Acoustic measurement + label narrowing (Modal + parselmouth)
├── vad_compare/ # Rust voice-activity-detection tool
└── inference/ # Run the model on your own audio
138 commits
Python
64.7%
Rust
30.8%
JavaScript
1.9%
Shell
1.8%