llm-annotator 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/PKG-INFO +1 -1
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/pyproject.toml +1 -1
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/src/llm_annotator/annotator.py +78 -41
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/.gitignore +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/.pre-commit-config.yaml +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/LICENSE +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/Makefile +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/README.md +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/examples/sentiment.py +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/src/llm_annotator/__init__.py +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/src/llm_annotator/utils.py +0 -0
- {llm_annotator-0.2.0 → llm_annotator-0.2.2}/tests/conftest.py +0 -0
|
@@ -98,10 +98,11 @@ class Annotator:
|
|
|
98
98
|
def _load_dataset(
|
|
99
99
|
self,
|
|
100
100
|
*,
|
|
101
|
-
dataset_name: str,
|
|
102
101
|
prompt_template: str,
|
|
103
102
|
pdout: Path,
|
|
104
103
|
idx_column: str,
|
|
104
|
+
dataset_name: str | None = None,
|
|
105
|
+
dataset: Dataset | None = None,
|
|
105
106
|
dataset_config: str = None,
|
|
106
107
|
data_dir: str | None = None,
|
|
107
108
|
dataset_split: str | None = None,
|
|
@@ -120,6 +121,7 @@ class Annotator:
|
|
|
120
121
|
|
|
121
122
|
Args:
|
|
122
123
|
dataset_name: Name or path of the dataset to load.
|
|
124
|
+
dataset: Pre-loaded dataset to use instead of loading from name/path.
|
|
123
125
|
pdout: Output directory for caching and results.
|
|
124
126
|
dataset_config: Dataset configuration name (optional).
|
|
125
127
|
data_dir: Data directory for local datasets (optional).
|
|
@@ -144,37 +146,37 @@ class Annotator:
|
|
|
144
146
|
if max_num_samples is not None and max_num_samples <= 0:
|
|
145
147
|
raise ValueError("'max_num_samples' must be a positive integer or None")
|
|
146
148
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
+
if not dataset_name and dataset is None:
|
|
150
|
+
raise ValueError("Either 'dataset_name' or 'dataset' must be provided")
|
|
149
151
|
|
|
150
152
|
# Split verification and defaulting
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
153
|
+
if dataset_name:
|
|
154
|
+
split_names = get_dataset_split_names(dataset_name)
|
|
155
|
+
if not dataset_split:
|
|
156
|
+
if len(split_names) == 1:
|
|
157
|
+
dataset_split = split_names[0]
|
|
158
|
+
else:
|
|
159
|
+
raise ValueError(
|
|
160
|
+
f"Dataset '{dataset_name}' has multiple splits {split_names}. "
|
|
161
|
+
"Please specify a split using the 'dataset_split' argument."
|
|
162
|
+
)
|
|
163
|
+
elif dataset_split not in split_names:
|
|
164
|
+
raise ValueError(f"Dataset '{dataset_name}' does not have a split named '{dataset_split}'")
|
|
162
165
|
|
|
163
166
|
pdout = Path(pdout)
|
|
164
167
|
p_cached_input_ds = pdout / f"{prefix}cached_input_dataset"
|
|
165
168
|
|
|
166
|
-
dataset = None
|
|
167
|
-
|
|
168
169
|
# If exists and not empty, try to load from cache. If loading the
|
|
169
170
|
# cached dataset fails (corrupted cache), fall back to loading from
|
|
170
171
|
# the original source.
|
|
172
|
+
loaded_ds = None
|
|
171
173
|
if use_cached_input_dataset and p_cached_input_ds.exists() and p_cached_input_ds.stat().st_size > 0:
|
|
172
|
-
|
|
173
|
-
dataset = Dataset.load_from_disk(p_cached_input_ds)
|
|
174
|
-
except Exception:
|
|
175
|
-
dataset = None
|
|
174
|
+
loaded_ds = Dataset.load_from_disk(p_cached_input_ds)
|
|
176
175
|
|
|
177
|
-
|
|
176
|
+
# Always prefer a locally cached dataset if available
|
|
177
|
+
if loaded_ds is not None:
|
|
178
|
+
dataset = loaded_ds
|
|
179
|
+
else:
|
|
178
180
|
if streaming and not max_num_samples:
|
|
179
181
|
raise ValueError(
|
|
180
182
|
"Streaming mode requires max_num_samples to be set."
|
|
@@ -182,7 +184,8 @@ class Annotator:
|
|
|
182
184
|
" the requested number of samples."
|
|
183
185
|
)
|
|
184
186
|
|
|
185
|
-
|
|
187
|
+
# No dataset provided, so got to load it from dataset_name
|
|
188
|
+
if dataset is None and streaming:
|
|
186
189
|
ds_iter: IterableDataset = load_dataset(
|
|
187
190
|
dataset_name, name=dataset_config, data_dir=data_dir, split=dataset_split, streaming=True
|
|
188
191
|
)
|
|
@@ -206,7 +209,12 @@ class Annotator:
|
|
|
206
209
|
# Convert to Dataset
|
|
207
210
|
dataset = Dataset.from_generator(yield_fn, split=dataset_split)
|
|
208
211
|
else:
|
|
209
|
-
|
|
212
|
+
# Use the provided dataset if available
|
|
213
|
+
if dataset is not None:
|
|
214
|
+
dataset = dataset
|
|
215
|
+
else:
|
|
216
|
+
dataset = load_dataset(dataset_name, name=dataset_config, data_dir=data_dir, split=dataset_split)
|
|
217
|
+
|
|
210
218
|
if shuffle_seed is not None:
|
|
211
219
|
dataset = dataset.shuffle(seed=shuffle_seed)
|
|
212
220
|
|
|
@@ -224,24 +232,18 @@ class Annotator:
|
|
|
224
232
|
dataset = self._preprocess_dataset(dataset=dataset)
|
|
225
233
|
|
|
226
234
|
dataset = dataset.map(
|
|
227
|
-
|
|
228
|
-
f"{prefix}prompted": self.tokenizer.apply_chat_template(
|
|
229
|
-
[
|
|
230
|
-
{
|
|
231
|
-
"role": "user",
|
|
232
|
-
"content": prompt_template.format(**{fld: sample[fld] for fld in prompt_fields}),
|
|
233
|
-
}
|
|
234
|
-
],
|
|
235
|
-
tokenize=False,
|
|
236
|
-
add_generation_template=True,
|
|
237
|
-
enable_thinking=self.enable_thinking,
|
|
238
|
-
),
|
|
239
|
-
idx_column: idx,
|
|
240
|
-
},
|
|
235
|
+
self.apply_prompt_template,
|
|
241
236
|
with_indices=True,
|
|
242
237
|
num_proc=self.num_proc,
|
|
238
|
+
fn_kwargs={
|
|
239
|
+
"prompt_fields": prompt_fields,
|
|
240
|
+
"prompt_template": prompt_template,
|
|
241
|
+
"idx_column": idx_column,
|
|
242
|
+
"prefix": prefix,
|
|
243
|
+
},
|
|
243
244
|
desc="Applying prompt template",
|
|
244
245
|
)
|
|
246
|
+
|
|
245
247
|
if cache_input_dataset:
|
|
246
248
|
dataset.save_to_disk(p_cached_input_ds)
|
|
247
249
|
|
|
@@ -265,6 +267,38 @@ class Annotator:
|
|
|
265
267
|
dataset = self._postprocess_dataset(dataset=dataset)
|
|
266
268
|
return dataset, processed_n_samples
|
|
267
269
|
|
|
270
|
+
def apply_prompt_template(
|
|
271
|
+
self, sample: dict, idx: int, prompt_fields: Iterable[str], prompt_template: str, idx_column: str, prefix: str
|
|
272
|
+
) -> dict[str, str | int]:
|
|
273
|
+
"""Apply the prompt template to a single dataset sample. Fills in the prompt template with values from the sample,
|
|
274
|
+
based on the prompt_fields.
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
sample: The dataset sample to process.
|
|
278
|
+
idx: The index of the sample in the dataset.
|
|
279
|
+
prompt_fields: Fields required by the prompt template.
|
|
280
|
+
prompt_template: The prompt template string with placeholders.
|
|
281
|
+
idx_column: Column name to use as unique identifier.
|
|
282
|
+
prefix: String prefix to use for internal column names.
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
A dictionary with the filled-in prompt and the sample index.
|
|
286
|
+
"""
|
|
287
|
+
return {
|
|
288
|
+
f"{prefix}prompted": self.tokenizer.apply_chat_template(
|
|
289
|
+
[
|
|
290
|
+
{
|
|
291
|
+
"role": "user",
|
|
292
|
+
"content": prompt_template.format(**{fld: sample[fld] for fld in prompt_fields}),
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
tokenize=False,
|
|
296
|
+
add_generation_template=True,
|
|
297
|
+
enable_thinking=self.enable_thinking,
|
|
298
|
+
),
|
|
299
|
+
idx_column: idx,
|
|
300
|
+
}
|
|
301
|
+
|
|
268
302
|
def _preprocess_dataset(self, *, dataset: Dataset) -> Dataset:
|
|
269
303
|
"""Preprocess the dataset before applying prompt templates.
|
|
270
304
|
|
|
@@ -433,9 +467,10 @@ class Annotator:
|
|
|
433
467
|
|
|
434
468
|
def annotate_dataset(
|
|
435
469
|
self,
|
|
436
|
-
dataset_name: str,
|
|
437
470
|
output_dir: str | Path,
|
|
438
471
|
*,
|
|
472
|
+
dataset_name: str | None = None,
|
|
473
|
+
dataset: Dataset | None = None,
|
|
439
474
|
new_hub_id: str | None = None,
|
|
440
475
|
overwrite: bool = False,
|
|
441
476
|
dataset_config: str | None = None,
|
|
@@ -465,8 +500,9 @@ class Annotator:
|
|
|
465
500
|
from dataset loading through model inference to output generation.
|
|
466
501
|
|
|
467
502
|
Args:
|
|
468
|
-
dataset_name: Name or path of the dataset to annotate.
|
|
469
503
|
output_dir: Directory to save annotation results.
|
|
504
|
+
dataset_name: Name or path of the dataset to annotate.
|
|
505
|
+
dataset: Pre-loaded dataset to use instead of loading from name/path.
|
|
470
506
|
new_hub_id: Optional Hugging Face dataset ID for uploads.
|
|
471
507
|
overwrite: Whether to overwrite existing output directory.
|
|
472
508
|
dataset_config: Dataset configuration name (optional).
|
|
@@ -564,10 +600,11 @@ class Annotator:
|
|
|
564
600
|
|
|
565
601
|
self._load_tokenizer()
|
|
566
602
|
dataset, processed_n_samples = self._load_dataset(
|
|
567
|
-
dataset_name=dataset_name,
|
|
568
603
|
prompt_template=prompt_template,
|
|
569
|
-
pdout=pdout,
|
|
570
604
|
idx_column=idx_column,
|
|
605
|
+
pdout=pdout,
|
|
606
|
+
dataset_name=dataset_name,
|
|
607
|
+
dataset=dataset,
|
|
571
608
|
dataset_config=dataset_config,
|
|
572
609
|
data_dir=data_dir,
|
|
573
610
|
dataset_split=dataset_split,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|