llm-annotator 0.2.4__tar.gz → 0.2.6__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.4 → llm_annotator-0.2.6}/PKG-INFO +1 -1
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/examples/sentiment.py +2 -2
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/src/llm_annotator/annotator.py +32 -7
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/.gitignore +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/.pre-commit-config.yaml +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/LICENSE +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/Makefile +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/README.md +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/pyproject.toml +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/src/llm_annotator/__init__.py +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/src/llm_annotator/utils.py +0 -0
- {llm_annotator-0.2.4 → llm_annotator-0.2.6}/tests/conftest.py +0 -0
|
@@ -32,11 +32,11 @@ def main():
|
|
|
32
32
|
dataset_split="test",
|
|
33
33
|
new_hub_id=f"{hf_user}/sentiment-imdb",
|
|
34
34
|
streaming=True,
|
|
35
|
-
max_num_samples=
|
|
35
|
+
max_num_samples=200,
|
|
36
36
|
cache_input_dataset=False, # `True` is generally useful, not for demo purposes
|
|
37
37
|
prompt_template=prompt_template,
|
|
38
38
|
output_schema=output_schema,
|
|
39
|
-
# Backup to HF every
|
|
39
|
+
# Backup to HF every 100 samples.
|
|
40
40
|
# In practice, set to a higher value (e.g., 1000+)
|
|
41
41
|
upload_every_n_samples=100,
|
|
42
42
|
)
|
|
@@ -3,6 +3,7 @@ import json
|
|
|
3
3
|
import shutil
|
|
4
4
|
import string
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
|
+
from functools import wraps
|
|
6
7
|
from math import ceil
|
|
7
8
|
from os import PathLike
|
|
8
9
|
from pathlib import Path
|
|
@@ -15,11 +16,29 @@ from tqdm import tqdm
|
|
|
15
16
|
from transformers import AutoTokenizer, PreTrainedTokenizer
|
|
16
17
|
from vllm import LLM, RequestOutput, SamplingParams
|
|
17
18
|
from vllm.distributed import destroy_distributed_environment, destroy_model_parallel
|
|
18
|
-
from vllm.sampling_params import
|
|
19
|
+
from vllm.sampling_params import StructuredOutputsParams
|
|
19
20
|
|
|
20
21
|
from llm_annotator.utils import remove_empty_jsonl_files, retry
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
def destroy_model_on_error(func):
|
|
25
|
+
@wraps(func)
|
|
26
|
+
def wrapper(self, *args, **kwargs):
|
|
27
|
+
try:
|
|
28
|
+
return func(self, *args, **kwargs)
|
|
29
|
+
except BaseException as e:
|
|
30
|
+
# Catch BaseException so we also clean on KeyboardInterrupt/SystemExit
|
|
31
|
+
try:
|
|
32
|
+
self.destroy_model()
|
|
33
|
+
except Exception as clean_err:
|
|
34
|
+
# Don't hide the original error; attach a note (Python 3.11+)
|
|
35
|
+
if hasattr(e, "__notes__"):
|
|
36
|
+
e.__notes__.append(f"Cleanup failed: {clean_err!r}")
|
|
37
|
+
raise # re-raise the original exception
|
|
38
|
+
|
|
39
|
+
return wrapper
|
|
40
|
+
|
|
41
|
+
|
|
23
42
|
@dataclass(slots=True)
|
|
24
43
|
class Annotator:
|
|
25
44
|
"""Sensible base class for LLM-based dataset annotation.
|
|
@@ -413,16 +432,21 @@ class Annotator:
|
|
|
413
432
|
"""
|
|
414
433
|
if isinstance(self.pipe, LLM):
|
|
415
434
|
destroy_model_parallel()
|
|
435
|
+
destroy_distributed_environment()
|
|
436
|
+
|
|
416
437
|
try:
|
|
417
438
|
self.pipe.llm_engine.model_executor.shutdown()
|
|
418
439
|
del self.pipe.llm_engine.model_executor
|
|
419
440
|
except Exception:
|
|
420
441
|
pass
|
|
442
|
+
try:
|
|
443
|
+
self.pipe.llm_engine.engine_core.shutdown()
|
|
444
|
+
del self.pipe.llm_engine.engine_core
|
|
445
|
+
except Exception:
|
|
446
|
+
pass
|
|
421
447
|
del self.pipe.llm_engine
|
|
422
448
|
del self.pipe
|
|
423
|
-
gc.collect()
|
|
424
449
|
cuda.empty_cache()
|
|
425
|
-
destroy_distributed_environment()
|
|
426
450
|
gc.collect()
|
|
427
451
|
|
|
428
452
|
self.pipe = None
|
|
@@ -447,7 +471,7 @@ class Annotator:
|
|
|
447
471
|
Returns:
|
|
448
472
|
List of processed output dictionaries for each sample in the batch.
|
|
449
473
|
"""
|
|
450
|
-
output_schema = sampling_params.
|
|
474
|
+
output_schema = sampling_params.structured_outputs.json if sampling_params.structured_outputs else None
|
|
451
475
|
outputs = self.pipe.generate(batch[f"{prefix}prompted"], sampling_params, use_tqdm=False)
|
|
452
476
|
results = [self._process_output(output=outp, output_schema=output_schema, prefix=prefix) for outp in outputs]
|
|
453
477
|
|
|
@@ -462,6 +486,7 @@ class Annotator:
|
|
|
462
486
|
|
|
463
487
|
return results
|
|
464
488
|
|
|
489
|
+
@destroy_model_on_error
|
|
465
490
|
def annotate_dataset(
|
|
466
491
|
self,
|
|
467
492
|
output_dir: str | Path,
|
|
@@ -632,11 +657,11 @@ class Annotator:
|
|
|
632
657
|
|
|
633
658
|
sampling_params = sampling_params or {}
|
|
634
659
|
if output_schema:
|
|
635
|
-
if "
|
|
660
|
+
if "structured_outputs" in sampling_params:
|
|
636
661
|
raise ValueError(
|
|
637
|
-
"If 'output_schema' is provided, do not set '
|
|
662
|
+
"If 'output_schema' is provided, do not set 'structured_outputs' in sampling_params yourself"
|
|
638
663
|
)
|
|
639
|
-
sampling_params["
|
|
664
|
+
sampling_params["structured_outputs"] = StructuredOutputsParams(
|
|
640
665
|
json=output_schema,
|
|
641
666
|
whitespace_pattern=whitespace_pattern,
|
|
642
667
|
)
|
|
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
|