This guide will help you upgrade your code to the latest version of AnglE, which includes significant refactoring to simplify the API and improve usability.
- Removed
AngleDataTokenizer- No need to pre-tokenize datasets - Removed
DatasetFormatsclass - Use string literals instead - Removed
check_llm()function - Setis_llmmanually - Removed command-line arguments:
--coword_random_mask_rate,--fix_data - Renamed
--prompt_templateto--text_prompt(Format A only) - New prompt parameters:
--query_prompt,--doc_prompt - Updated data format requirements
- Training examples now use
accelerate launchinstead oftorchrun
Before (v0.5.x):
from datasets import load_dataset
from angle_emb import AnglE, AngleDataTokenizer
angle = AnglE.from_pretrained('model-name', max_length=128, pooling_strategy='cls').cuda()
ds = load_dataset('your-dataset')
# Had to pre-tokenize the dataset
train_ds = ds['train'].shuffle().map(
AngleDataTokenizer(angle.tokenizer, angle.max_length),
num_proc=8
)
angle.fit(train_ds=train_ds, ...)After (v0.6.0):
from datasets import load_dataset
from angle_emb import AnglE
angle = AnglE.from_pretrained('model-name', max_length=128, pooling_strategy='cls').cuda()
ds = load_dataset('your-dataset')
# Just load the raw dataset - tokenization happens automatically!
train_ds = ds['train'].shuffle()
angle.fit(train_ds=train_ds, ...)Before (v0.5.x):
from angle_emb import DatasetFormats
# Format A
dataset_format = DatasetFormats.A
# Format B
dataset_format = DatasetFormats.B
# Format C
dataset_format = DatasetFormats.CAfter (v0.6.0):
# Use string literals directly
dataset_format = 'A' # or 'B' or 'C'Format A (text1, text2, label):
text1: strtext2: strlabel: float (similarity score, e.g., 0-1)
Format B (query, positive):
# Old field names (deprecated)
{"text": "...", "positive": "..."}
# New field names (required)
{"query": "...", "positive": "..."}
# Can also use lists - one will be randomly sampled
{"query": ["query1", "query2"], "positive": ["pos1", "pos2"]}Format C (query, positive, negative):
# Old field names (deprecated)
{"text": "...", "positive": "...", "negative": "..."}
# New field names (required)
{"query": "...", "positive": "...", "negative": "..."}
# Can also use lists - one will be randomly sampled
{"query": "...", "positive": ["pos1", "pos2"], "negative": ["neg1", "neg2"]}💡 Pro Tip: Use --column_rename_mapping to migrate old datasets without modification!
If your existing dataset uses old field names, you can remap them using the --column_rename_mapping argument:
# Example: Remap "text" to "query"
angle-trainer \
--train_name_or_path your-dataset \
--column_rename_mapping "text:query" \
...
# You can also use it in Python code:
from angle_emb import AnglE
angle = AnglE.from_pretrained('model-name').cuda()
# Your old dataset with "text" field
ds = load_dataset('your-old-dataset') # Has "text" field
angle.fit(
train_ds=ds['train'],
column_rename_mapping={"text": "query"}, # Remap on the fly!
...
)Before (v0.5.x):
# is_llm was auto-detected based on model name patterns
angle = AnglE.from_pretrained(
'NousResearch/Llama-2-7b-hf',
pretrained_lora_path='path/to/lora',
pooling_strategy='last'
).cuda()After (v0.6.0):
# Must manually set is_llm=True
angle = AnglE.from_pretrained(
'NousResearch/Llama-2-7b-hf',
pretrained_lora_path='path/to/lora',
pooling_strategy='last',
is_llm=True # ⚠️ Required!
).cuda()Before (v0.5.x):
# Single prompt parameter for all texts
angle.fit(
train_ds=train_ds,
prompt_template="Represent this sentence: {text}",
...
)After (v0.6.0):
# Different prompts for different fields
# For Format A (text1, text2, label)
angle.fit(
train_ds=train_ds,
text_prompt="Represent this sentence: {text}", # Applied to both text1 and text2
...
)
# For Format B/C (query, positive, negative)
angle.fit(
train_ds=train_ds,
query_prompt="query: {text}", # Applied to query field
doc_prompt="doc: {text}", # Applied to positive/negative fields
...
)Before (v0.5.x):
CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun \
--nproc_per_node=4 \
--master_port=1234 \
-m angle_emb.angle_trainer \
--train_name_or_path dataset-name \
--model_name_or_path model-name \
--prompt_template "Represent: {text}" \
...After (v0.6.0):
CUDA_VISIBLE_DEVICES=0,1,2,3 WANDB_MODE=disabled accelerate launch \
--multi_gpu \
--num_processes 4 \
--main_process_port 1234 \
-m angle_emb.angle_trainer \
--train_name_or_path dataset-name \
--model_name_or_path model-name \
--query_prompt "query: {text}" \
--doc_prompt "doc: {text}" \
--is_llm 1 \ # If using LLM
...Before (v0.5.x):
# evaluate() returned tuple (corrcoef, accuracy)
corrcoef, accuracy = angle.evaluate(test_ds, device=angle.device)
print(f'corrcoef: {corrcoef}, accuracy: {accuracy}')After (v0.6.0):
# evaluate() returns only corrcoef for Format A datasets
corrcoef = angle.evaluate(test_ds)
print(f'Spearman corrcoef: {corrcoef}')--coword_random_mask_rate❌--fix_data❌--prompt_template❌ (renamed)
--text_prompt✅ (replaces--prompt_template, Format A only)--query_prompt✅ (for query field in Format B/C)--doc_prompt✅ (for positive/negative fields in Format B/C)--column_rename_mapping✅ (remap old column names to new ones)
--is_llm 1must be explicitly set for LLM models- Use
accelerate launchinstead oftorchrunfor distributed training - Use
--column_rename_mappingto adapt old datasets without modifying them
Before:
from datasets import load_dataset
from angle_emb import AnglE, AngleDataTokenizer
angle = AnglE.from_pretrained('bert-base-uncased', max_length=128, pooling_strategy='cls').cuda()
ds = load_dataset('mteb/stsbenchmark-sts')
ds = ds.map(lambda obj: {"text1": obj["sentence1"], "text2": obj["sentence2"], "label": obj['score']})
train_ds = ds['train'].map(AngleDataTokenizer(angle.tokenizer, angle.max_length), num_proc=8)
angle.fit(train_ds=train_ds, ...)After:
from datasets import load_dataset
from angle_emb import AnglE
angle = AnglE.from_pretrained('bert-base-uncased', max_length=128, pooling_strategy='cls').cuda()
ds = load_dataset('mteb/stsbenchmark-sts')
ds = ds.map(lambda obj: {"text1": obj["sentence1"], "text2": obj["sentence2"], "label": obj['score']})
# No need to tokenize!
angle.fit(train_ds=ds['train'], ...)Before:
# Dataset with "text" and "positive" fields
ds = [{"text": "query", "positive": "pos"}]
train_ds = Dataset.from_list(ds).map(AngleDataTokenizer(tokenizer, max_length), num_proc=8)After (Option 1 - Modify dataset):
# Must rename "text" to "query"
ds = [{"query": "query", "positive": "pos"}]
train_ds = Dataset.from_list(ds) # No tokenization needed!
# Use query_prompt and doc_prompt
angle.fit(
train_ds=train_ds,
query_prompt="query: {text}",
doc_prompt="doc: {text}",
...
)After (Option 2 - Use column_rename_mapping):
# Keep old dataset with "text" field - just remap it!
ds = [{"text": "query", "positive": "pos"}]
train_ds = Dataset.from_list(ds)
# Use column_rename_mapping to adapt old data
angle.fit(
train_ds=train_ds,
column_rename_mapping={"text": "query"}, # Automatic remapping!
query_prompt="query: {text}",
doc_prompt="doc: {text}",
...
)Command-line example:
# With --column_rename_mapping, no need to modify dataset!
accelerate launch -m angle_emb.angle_trainer \
--train_name_or_path your-old-dataset \
--column_rename_mapping "text:query" \
--query_prompt "query: {text}" \
--doc_prompt "doc: {text}" \
...Before:
# is_llm was auto-detected
torchrun -m angle_emb.angle_trainer \
--model_name_or_path NousResearch/Llama-2-7b-hf \
--apply_lora 1 \
...After:
# Must explicitly set is_llm
accelerate launch -m angle_emb.angle_trainer \
--model_name_or_path NousResearch/Llama-2-7b-hf \
--is_llm 1 \
--apply_lora 1 \
...If you encounter issues during migration:
- Check the updated documentation
- Review the examples
- Open an issue on GitHub
- Simpler API: No need to pre-tokenize datasets
- More flexible: Support for list-based sampling in Format B/C
- Better prompting: Separate prompts for queries and documents
- Clearer configuration: Explicit
is_llmsetting - Modern training:
accelerate launchsupport out of the box - Backward compatibility: Use
--column_rename_mappingto adapt old datasets without modification
Happy upgrading! 🚀
The --column_rename_mapping / column_rename_mapping parameter makes migration easier by allowing you to remap old column names to new ones without modifying your dataset.
Syntax:
- Command-line:
--column_rename_mapping "old_name:new_name" - Python:
column_rename_mapping={"old_name": "new_name"}
Common use cases:
# Remap "text" to "query" for Format B/C datasets
--column_rename_mapping "text:query"
# Multiple remappings (separate with semicolons in CLI)
--column_rename_mapping "text:query;sentence1:text1;sentence2:text2"Python example:
angle.fit(
train_ds=old_dataset,
column_rename_mapping={
"text": "query",
"sentence1": "text1",
"sentence2": "text2"
},
...
)This allows you to use existing datasets without any preprocessing!