zensols.lmtask package¶
Submodules¶
zensols.lmtask.app module¶
Task-specialized language model training and inference.
- class zensols.lmtask.app.Application(config_factory, task_factory)[source]¶
Bases:
objectTask-specialized language model training and inference.
- __init__(config_factory, task_factory)¶
- property benchmark_runner: BenchmarkRunner¶
Used to lTrain, test, score and render one configured LMTask benchmark.
-
config_factory:
ConfigFactory¶ Used to create configured application and training resources.
- dataset_sample(max_sample=1)[source]¶
Print sample(s) of the configured (
--config) dataset.- Parameters:
max_sample (
int) – the number of sample to print
- instruct(task_name, instruction, role=None, output_format=None)[source]¶
Generate text by inferencing with the model.
- report(configs, base_dir=None)[source]¶
Create a report.
- Parameters:
base_dir (
Path) – root directory to create files, or render if not given
- show_task(task_name=None)[source]¶
Print the configuration of a task if
--nameis given, otherise a list of available tasks.- Parameters:
task_name (
str) – the task that creates the prompt and parses the result
- show_trainer(long_output=False)[source]¶
Print configuration and dataset stats of the configured (
--config) trainer.- Parameters:
long_output (
bool) – verbosity
-
task_factory:
TaskFactory¶ Create tasks used to fulfill CLI requests.
- test(output_file=PosixPath('-'), output_format=None)[source]¶
Test a trained model on a configured (
--config) dataset.- Parameters:
output_file (
Path) – output file name,-for standard outoutput_format (
_Format) – data format for the output
- property tester: Tester¶
The currently configured
test.Tester.
- property trainer: Trainer¶
The currently configured
train.Trainer.
zensols.lmtask.benchmark module¶
Reproducible LMTask benchmark execution and reporting.
The benchmark JSON file is the source of truth. Markdown is rendered from that structured result so reports can be regenerated without retraining a model.
- class zensols.lmtask.benchmark.BenchmarkResult(name, task_name, model_name, config_file, created, git, environment, datasets, training, testing, metrics, notes=())[source]¶
Bases:
DictableComplete machine-readable benchmark record.
- __init__(name, task_name, model_name, config_file, created, git, environment, datasets, training, testing, metrics, notes=())¶
-
created:
str¶ The timezone-aware ISO-8601 timestamp recording when the benchmark result was created.
-
datasets:
DatasetSplitsResult¶ The train, validation and held-out test split metadata.
- property describer: DataDescriber¶
Create a data describer for the results in this benchmark.
-
environment:
EnvironmentResult¶ The software, CUDA and hardware environment information.
-
metrics:
MetricsResult¶ The performance metrics for this benchmark.
-
name:
str¶ Name of the run copied from
BenchmarkRunner.name.
-
testing:
TestingResult¶ The held-out task-inference metadata.
-
training:
TrainingResult¶ The model-training diagnostics and persisted adapter metadata.
- class zensols.lmtask.benchmark.BenchmarkRunner(name, task_name, model_name, config_file, trainer, tester, metrics_calculator, executor, result_dir, template_dir, temporary_dir, detail_template='overview.md.jinja2', prediction_format='jsonl', class_count_column=None)[source]¶
Bases:
DictableTrain, test, score and render one configured LMTask benchmark.
- __init__(name, task_name, model_name, config_file, trainer, tester, metrics_calculator, executor, result_dir, template_dir, temporary_dir, detail_template='overview.md.jinja2', prediction_format='jsonl', class_count_column=None)¶
-
class_count_column:
str|None= None¶ The dataset column used for per-split class counts;
Nonedisables class counting.
-
config_file:
Path¶ The configuration file used for training and testing.
- property datasets: DatasetSplitsResult¶
Collect metadata for configured train, validation and test splits.
-
detail_template:
str= 'overview.md.jinja2'¶ The Jinja2 template filename used to render the per-benchmark Markdown report.
-
executor:
Executor¶ The command executor used to collect external provenance such as Git and NVIDIA information.
-
metrics_calculator:
MetricsCalculator¶ The task-specific metric implementation selected by the
trainconfconfiguration.
-
name:
str¶ Name of the run, usually taken from the
lmtask_benchmark:name, which is composed of the dataset and model name.
-
prediction_format:
str= 'jsonl'¶ The persisted prediction format; reserved for future formats beyond JSONL.
- property result: BenchmarkResult¶
Train, test, score, persist and render this benchmark.
-
result_dir:
Path¶ Output director for the generated benchmark files.
-
template_dir:
Path¶ The directory containing benchmark Jinja2 templates.
-
temporary_dir:
Path¶ Directory to store temporary files.
- class zensols.lmtask.benchmark.DatasetSplit(name, examples, class_counts=None)[source]¶
Bases:
DictableDataset split size and optional class distribution.
- __init__(name, examples, class_counts=None)¶
- class zensols.lmtask.benchmark.DatasetSplitsResult(splits)[source]¶
Bases:
DictableContains the dataset splits.
- __init__(splits)¶
-
splits:
tuple[DatasetSplit,...]¶ The dataset splits.
- class zensols.lmtask.benchmark.EnvironmentResult(python, os, kernel, cuda_visible_devices, cuda_runtime, nvidia_driver, packages=<factory>, gpus=())[source]¶
Bases:
DictableSoftware and hardware environment used for the benchmark.
- __init__(python, os, kernel, cuda_visible_devices, cuda_runtime, nvidia_driver, packages=<factory>, gpus=())¶
- class zensols.lmtask.benchmark.GitResult(commit, describe, dirty)[source]¶
Bases:
DictableRepository revision used for the benchmark.
- __init__(commit, describe, dirty)¶
- class zensols.lmtask.benchmark.GpuResult(index, name, total_memory, peak_allocated=None, peak_reserved=None)[source]¶
Bases:
DictableOne CUDA device visible to the benchmark process.
- __init__(index, name, total_memory, peak_allocated=None, peak_reserved=None)¶
-
peak_allocated:
int|None= None¶ The peak memory allocated by PyTorch during benchmark execution in bytes;
Nonewhen unavailable.
- class zensols.lmtask.benchmark.TestingResult(test_result, predictions_file)[source]¶
Bases:
DictableHeld-out task testing facts.
- __init__(test_result, predictions_file)¶
-
predictions_file:
Path¶ The path to the predictions JSONL file.
-
test_result:
TestResult¶ Result from
test.Tester.
- class zensols.lmtask.benchmark.TrainingResult(elapsed_seconds, global_step, training_loss, metrics, result_dir, adapter_size=None)[source]¶
Bases:
DictableTraining facts captured from LMTask and the generated adapter.
- __init__(elapsed_seconds, global_step, training_loss, metrics, result_dir, adapter_size=None)¶
zensols.lmtask.cli module¶
Command line entry point to the application.
- class zensols.lmtask.cli.ApplicationFactory(*args, **kwargs)[source]¶
Bases:
ApplicationFactory
zensols.lmtask.dataset module¶
An implementation of a dataset generator task.TaskDatasetFactory.
- class zensols.lmtask.dataset.LoadedTaskDatasetFactory(task, text_field='text', messages_field='messages', source=None, load_args=<factory>, pre_process=None, post_process=None)[source]¶
Bases:
TaskDatasetFactoryA utility class meant to be created from an application configuration. This class creates a dataframe used by
Trainerand optionally does post processing (i.e. filtering and mapping).- __init__(task, text_field='text', messages_field='messages', source=None, load_args=<factory>, pre_process=None, post_process=None)¶
-
post_process:
str|Callable= None¶ Code to call after the dataset is created and the task has applied any template.
- See:
zensols.lmtask.gemma4 module¶
Temporary fix to get Gemma 4 to fine-tune with LoRA.
- class zensols.lmtask.gemma4.Gemma4GeneratorResource(name, model_id, model_class=<class 'transformers.models.auto.modeling_auto.AutoModelForCausalLM'>, tokenizer_class=<class 'transformers.models.auto.tokenization_auto.AutoTokenizer'>, peft_model_id=None, peft_model_class=<class 'peft.auto.AutoPeftModelForCausalLM'>, model_desc=None, system_role_name='system', tokenizer_args=<factory>, model_args=<factory>)[source]¶
Bases:
GeneratorResourceA class to “monkey patch” the an open issue with using Gemma 4 for text only SFT with LoRA.
- Link:
- Link:
- __init__(name, model_id, model_class=<class 'transformers.models.auto.modeling_auto.AutoModelForCausalLM'>, tokenizer_class=<class 'transformers.models.auto.tokenization_auto.AutoTokenizer'>, peft_model_id=None, peft_model_class=<class 'peft.auto.AutoPeftModelForCausalLM'>, model_desc=None, system_role_name='system', tokenizer_args=<factory>, model_args=<factory>)¶
- class zensols.lmtask.gemma4.Gemma4HFTrainerResource(model_args=None, cache=True, generator_resource=None, peft_config=None)[source]¶
Bases:
HFTrainerResource- __init__(model_args=None, cache=True, generator_resource=None, peft_config=None)¶
zensols.lmtask.generate module¶
Facade to HuggingFace text generation.
- class zensols.lmtask.generate.CachingGenerator(_delegate, _stash, _hasher=<factory>)[source]¶
Bases:
TextGeneratorA generator that caches response using a hash of the model input as a key.
- __init__(_delegate, _stash, _hasher=<factory>)¶
- class zensols.lmtask.generate.ConfigGeneratorResource(name, model_id, model_class=<class 'transformers.models.auto.modeling_auto.AutoModelForCausalLM'>, tokenizer_class=<class 'transformers.models.auto.tokenization_auto.AutoTokenizer'>, peft_model_id=None, peft_model_class=<class 'peft.auto.AutoPeftModelForCausalLM'>, model_desc=None, system_role_name='system', tokenizer_args=<factory>, model_args=<factory>, code_tokenizer=None, code_model=None)[source]¶
Bases:
GeneratorResourceAllows inline Python codee to configure tokenizers and models.
- __init__(name, model_id, model_class=<class 'transformers.models.auto.modeling_auto.AutoModelForCausalLM'>, tokenizer_class=<class 'transformers.models.auto.tokenization_auto.AutoTokenizer'>, peft_model_id=None, peft_model_class=<class 'peft.auto.AutoPeftModelForCausalLM'>, model_desc=None, system_role_name='system', tokenizer_args=<factory>, model_args=<factory>, code_tokenizer=None, code_model=None)¶
- class zensols.lmtask.generate.ConstantTextGenerator(config_factory, response, post_init_source=None)[source]¶
Bases:
TextGeneratorA generator that responses with
responsewith every generation call for the purpose of debugging.- __init__(config_factory, response, post_init_source=None)¶
-
config_factory:
ConfigFactory¶ Used to set optional mock attributes in
post_init_source.
- class zensols.lmtask.generate.GenerateTask(name, description, request_class, response_class, generator, resource, train_add_eos=False)[source]¶
Bases:
TaskUses a
TextGenerator(generator) to generate a response.- __init__(name, description, request_class, response_class, generator, resource, train_add_eos=False)¶
-
generator:
TextGenerator¶ A client facade of a chat or instruct-based large language model.
-
resource:
GeneratorResource¶ The class that creates resources such as the tokenizer and model. This should be the base model resource so training tasks do not depend on the model they will eventually create.
This is also used by
InstructTaskfor its chat template.
- class zensols.lmtask.generate.GeneratorOutput(model_output, parsed)[source]¶
Bases:
DictableContainer instances of model output from
TextGenerator.- __init__(model_output, parsed)¶
- class zensols.lmtask.generate.GeneratorResource(name, model_id, model_class=<class 'transformers.models.auto.modeling_auto.AutoModelForCausalLM'>, tokenizer_class=<class 'transformers.models.auto.tokenization_auto.AutoTokenizer'>, peft_model_id=None, peft_model_class=<class 'peft.auto.AutoPeftModelForCausalLM'>, model_desc=None, system_role_name='system', tokenizer_args=<factory>, model_args=<factory>)[source]¶
Bases:
DictableA client facade of a chat-based large language model.
- __init__(name, model_id, model_class=<class 'transformers.models.auto.modeling_auto.AutoModelForCausalLM'>, tokenizer_class=<class 'transformers.models.auto.tokenization_auto.AutoTokenizer'>, peft_model_id=None, peft_model_class=<class 'peft.auto.AutoPeftModelForCausalLM'>, model_desc=None, system_role_name='system', tokenizer_args=<factory>, model_args=<factory>)¶
- classmethod get_model_path(model_id, parent=None)[source]¶
Create a normalized file name from a HF model ID string useful for creating checkpoint directory names.
- Parameters:
model_id (
str) – the model ID (i.e.meta-llama/Llama-3.1-8B)parent (
Path) – the base directory used in the return value if given
- Return type:
Path
- property model: PreTrainedModel¶
The LLM.
- model_class¶
The class used to create the model with
from_pretrained().alias of
AutoModelForCausalLM
- property model_file_name: str¶
A normalized file name friendly string based on
model_desc.
- peft_model_class¶
The class used to create the model with
from_pretrained().alias of
AutoPeftModelForCausalLM
-
peft_model_id:
str|Path= None¶ The HF model ID or path to the Peft model or
Noneif there is none.
- property tokenizer: PreTrainedTokenizer¶
The model’s tokenzier.
- tokenizer_class¶
The class used to create the tokenizer with
from_pretrained().alias of
AutoTokenizer
- class zensols.lmtask.generate.ModelTextGenerator(resource, tokenize_params=<factory>, tokenize_decode_params=<factory>, generate_params=<factory>, generation_config=<factory>, remove_generation_config=(), stream_args=<factory>, chat_template_args=<factory>)[source]¶
Bases:
TextGeneratorAn implementation that uses HuggingFace framework classes from
GeneratorResourceto answer queries.- __init__(resource, tokenize_params=<factory>, tokenize_decode_params=<factory>, generate_params=<factory>, generation_config=<factory>, remove_generation_config=(), stream_args=<factory>, chat_template_args=<factory>)¶
-
chat_template_args:
dict[str,Any]¶ Arguments given to
apply_chat_template. Some models require chat templates that allinstruct.InstructTaskshould add. For example, Qwen 3 always needsadd_generation_prompt=True.This only is used (and should only be set) in generators used by instruct tasks.
-
generation_config:
dict[str,Any]¶ The generation parameter for the model defaults
generation_config.
-
resource:
GeneratorResource¶ The class that creates resources such as the tokenizer and model.
- stream(prompt, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, width=80)[source]¶
Stream the model’s output from a
promptinput.- Parameters:
prompt (
str) – the input to give to the modelwriter (
TextIOBase) – the data sinkwidth (
int) – the maximum width of each line’s streamed text; ifNone, no modification will be done on the text output
- class zensols.lmtask.generate.ReplaceTextGenerator(resource, tokenize_params=<factory>, tokenize_decode_params=<factory>, generate_params=<factory>, generation_config=<factory>, remove_generation_config=(), stream_args=<factory>, chat_template_args=<factory>, replacements=())[source]¶
Bases:
ModelTextGeneratorA text generator that generates response by replacing regular expressions. This is helpful for removing special tokens.
- __init__(resource, tokenize_params=<factory>, tokenize_decode_params=<factory>, generate_params=<factory>, generation_config=<factory>, remove_generation_config=(), stream_args=<factory>, chat_template_args=<factory>, replacements=())¶
-
replacements:
tuple[tuple[str|Pattern,str,str|None],...] = ()¶ The a tuple
(<regular expression>, <replacement>[, flags])to replace in the parsed output from the model. String patters are compiled withre.compile().The third element is a comma-separate list of regular expression
reflags, such asDOTALLgets passed asre.subs(..., flags=re.DOTALL).
zensols.lmtask.hf module¶
HuggingFace trainer wrapper.
- class zensols.lmtask.hf.HFTrainerResource(model_args=None, cache=True, generator_resource=None, peft_config=None)[source]¶
Bases:
TrainerResourceUses
HuggingFaceTrainerfor training the model.- __init__(model_args=None, cache=True, generator_resource=None, peft_config=None)¶
-
generator_resource:
GeneratorResource= None¶ The resource used to the source checkpoint.
-
peft_config:
LoraConfig= None¶ The PEFT low-rank adapter configuration.
- class zensols.lmtask.hf.HuggingFaceTrainer(config, resource, train_params, eval_params, train_source, eval_source, peft_output_dir, result_file)[source]¶
Bases:
TrainerThe HuggingFace trainer.
- __init__(config, resource, train_params, eval_params, train_source, eval_source, peft_output_dir, result_file)¶
zensols.lmtask.instruct module¶
Task implementations.
- class zensols.lmtask.instruct.InstructModelTextGenerator(resource, tokenize_params=<factory>, tokenize_decode_params=<factory>, generate_params=<factory>, generation_config=<factory>, remove_generation_config=(), stream_args=<factory>, chat_template_args=<factory>, replacements=())[source]¶
Bases:
ReplaceTextGeneratorA generator that uses instruct based models for inference.
- __init__(resource, tokenize_params=<factory>, tokenize_decode_params=<factory>, generate_params=<factory>, generation_config=<factory>, remove_generation_config=(), stream_args=<factory>, chat_template_args=<factory>, replacements=())¶
- class zensols.lmtask.instruct.InstructTask(name, description, request_class, response_class, generator, resource, train_add_eos=False, role='You are a helpful assistant.', train_template='### Question: {{ instruction }}\\n### Answer: {{ output }}', inference_template='{{request.instruction}}', chat_template_args=<factory>, apply_chat_template=True, train_apply_chat_template=False)[source]¶
Bases:
GenerateTaskA task that is resolved using instructions given to the language model.
Important: If
InstructTaskRequest.model_inputis non-Nonethat value is used verbatim andInstructTaskRequest.instructionis ignored.- __init__(name, description, request_class, response_class, generator, resource, train_add_eos=False, role='You are a helpful assistant.', train_template='### Question: {{ instruction }}\\n### Answer: {{ output }}', inference_template='{{request.instruction}}', chat_template_args=<factory>, apply_chat_template=True, train_apply_chat_template=False)¶
-
apply_chat_template:
bool= True¶ Whether format the prompt into one that conforms to the model’s instruct syntax.
-
train_apply_chat_template:
bool= False¶ Whether to add
apply_chat_templateparameters to theapply_chat_templatecall during training. If this isFalse, a conversationalmessageswith dictionary list is used instead.
-
train_template:
str|Path= '### Question: {{ instruction }}\n### Answer: {{ output }}'¶ Used to create format the datasets training text
generator.
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- class zensols.lmtask.instruct.InstructTaskRequest(model_input=None, instruction=None)[source]¶
Bases:
TaskRequestA request that has a query portion to be added to the compiled prompt.
- __init__(model_input=None, instruction=None)¶
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, include_instruction=True)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- class zensols.lmtask.instruct.NShotTaskRequest(model_input=None, instruction=None, examples=None)[source]¶
Bases:
InstructTaskRequestA request that adds training examples to the prompt.
- __init__(model_input=None, instruction=None, examples=None)¶
zensols.lmtask.metric module¶
Task-level benchmark metrics.
Metric semantics are intentionally separated from benchmark execution so each task configuration can select the appropriate scorer (classification, regression, multilabel, generation, etc.).
- class zensols.lmtask.metric.ClassMetric(label, precision, recall, f1, support)[source]¶
Bases:
DictableMetrics computed for a single class.
- __init__(label, precision, recall, f1, support)¶
- class zensols.lmtask.metric.ClassificationMetricsCalculator(label_column='label', prediction_column='prediction', averages=('micro', 'macro', 'weighted'), primary_average='macro', primary_metric='f1', labels=None)[source]¶
Bases:
MetricsCalculatorSingle-label classification metrics.
- __init__(label_column='label', prediction_column='prediction', averages=('micro', 'macro', 'weighted'), primary_average='macro', primary_metric='f1', labels=None)¶
-
averages:
tuple[str,...] = ('micro', 'macro', 'weighted')¶ The averaging strategies used for aggregate precision, recall and F1 metrics.
- calculate(df)[source]¶
Return task-specific benchmark metrics.
- Parameters:
df (
DataFrame) – tester output containing gold labels and model predictions- Return type:
- Returns:
the computed task metrics
- class zensols.lmtask.metric.Metric(name, value, average=None)[source]¶
Bases:
DictableA scalar benchmark metric.
- __init__(name, value, average=None)¶
- class zensols.lmtask.metric.MetricsCalculator(label_column='label', prediction_column='prediction')[source]¶
Bases:
DictableCalculate task-level metrics from tester prediction rows.
- __init__(label_column='label', prediction_column='prediction')¶
- class zensols.lmtask.metric.MetricsResult(primary, support, metrics, per_class=(), invalid_count=0)[source]¶
Bases:
DictableTask-specific metrics returned by a
MetricsCalculator.- __init__(primary, support, metrics, per_class=(), invalid_count=0)¶
- property aggregate_dataframe: DataFrame¶
The aggregate metric results as a dataframe
- property aggregate_row: DataFrameDescriber¶
The aggregate metric and counts in row-form as a data describer.
-
invalid_count:
int= 0¶ The number of predictions that could not be interpreted as valid task outputs.
-
per_class:
tuple[ClassMetric,...] = ()¶ Optional per-class metrics; empty when per-class reporting does not apply.
- property per_class_dataframe: DataFrameDescriber¶
The per class metrics as a dataframe.
zensols.lmtask.proto module¶
Prototyping.
- class zensols.lmtask.proto.PrototypeApplication(config_factory, app, prompt='Once upon a time, in a galaxy, far far away,')[source]¶
Bases:
objectUsed by the Python REPL for prototyping.
- CLI_META = {'is_usage_visible': False}¶
- __init__(config_factory, app, prompt='Once upon a time, in a galaxy, far far away,')¶
-
app:
Application¶
-
config_factory:
ConfigFactory¶
zensols.lmtask.task module¶
Task implementations.
- class zensols.lmtask.task.JSONTaskResponse(request, model_output_raw, model_output, robust_json=True)[source]¶
Bases:
TaskResponseA task that parses the responses as JSON. The JSON is parsed as much as possible and does not raise errors when the json is incomplete.
- __init__(request, model_output_raw, model_output, robust_json=True)¶
- property model_output_json: Failure | str¶
The
responseattribute parsed as JSON.- Raises:
json.decoder.JSONDecodeError – if the JSON failed to parse
- See:
obj:robust_json
- robust_json: bool = True¶
Whether to return
Failurefrommodel_output_jsoninstead of raising from parse failures.
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, include_request=False, include_model_output=False, include_json=True)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- class zensols.lmtask.task.Task(name, description, request_class, response_class)[source]¶
Bases:
DictableSubclasses turn a prompt and query into a response from an LLM.
- __init__(name, description, request_class, response_class)¶
- prepare_dataset(ds, factory)[source]¶
Massage the any data for training necessary to train this task. This might involve apply templates and/or adding terminating tokens.
- Return type:
Dataset
- prepare_request(request)[source]¶
Return a request with the contents populated with a formatted prompt.
- Return type:
- process(request)[source]¶
Invoke the
generatorto query the LLM, then return a JSON formatted data.- Parameters:
query – a query that is phrased with the assumption that JSON is given as a response
- Return type:
-
request_class:
type[TaskRequest]¶ The response data.
-
response_class:
type[TaskResponse]¶ The response data.
- class zensols.lmtask.task.TaskDatasetFactory(task, text_field='text', messages_field='messages')[source]¶
Bases:
DictableSubclasses create a dataframes used by
Trainerand optionally does post processing (i.e. filtering and mapping).- __init__(task, text_field='text', messages_field='messages')¶
- create()[source]¶
Create a new dataset based on
source.- Return type:
Dataset- Returns:
the new dataset after modification by
post_process
-
messages_field:
str= 'messages'¶ The target conversational field used by the trainer or
Noneto not add it.
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- exception zensols.lmtask.task.TaskDatasetFactoryError(message, prompt=None)[source]¶
Bases:
TaskErrorRaised when
TaskDatasetFactoryinstances can not create datasets.- __firstlineno__ = 161¶
- __module__ = 'zensols.lmtask.task'¶
- __static_attributes__ = ()¶
- exception zensols.lmtask.task.TaskError(message, prompt=None)[source]¶
Bases:
APIErrorRaised for any LLM specific error in this API.
- __annotations__ = {}¶
- __firstlineno__ = 24¶
- __module__ = 'zensols.lmtask.task'¶
- __static_attributes__ = ('prompt',)¶
- class zensols.lmtask.task.TaskFactory(config_factory, _task_pattern)[source]¶
Bases:
DictableCreates instances of
Taskusingcreate().- __init__(config_factory, _task_pattern)¶
-
config_factory:
ConfigFactory¶ The factory that creates tasks.
- create(name)[source]¶
Create a new instance of a task with
nameper the app config.- See:
- Return type:
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, short=False)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- class zensols.lmtask.task.TaskObject[source]¶
Bases:
PersistableContainer,DictableBase class for task requests and responses.
- __init__()¶
- class zensols.lmtask.task.TaskRequest(model_input=None)[source]¶
Bases:
TaskObjectThe input request to the LLM via
Task.process(). In most cases, obj:model_input can be used to skip the prompt compilation step.- __init__(model_input=None)¶
- model_input: str = None¶
The text given verbatim to the model. This is some combination of both
quertyandprompt.
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- class zensols.lmtask.task.TaskResponse(request, model_output_raw, model_output)[source]¶
Bases:
TaskObjectThe happy-path response given by
Task.- __init__(request, model_output_raw, model_output)¶
- model_output: str¶
This task instance’s parsed response text given by the model.
- model_output_raw: str¶
The model output verbatim.
- request: TaskRequest¶
The request used to generated this response.
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, include_request=False, include_model_output=True, include_model_output_raw=False)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
zensols.lmtask.test module¶
Classes to test a model on datasets.
- exception zensols.lmtask.test.TestError[source]¶
Bases:
APIError- __annotations__ = {}¶
- __firstlineno__ = 26¶
- __module__ = 'zensols.lmtask.test'¶
- __static_attributes__ = ()¶
- class zensols.lmtask.test.TestResult(prediction_col, raw_col, time_elapsed, predictions)[source]¶
Bases:
PersistableContainer,DictableResults from the a test run.
- __init__(prediction_col, raw_col, time_elapsed, predictions)¶
- property dataframe: DataFrame¶
The dataframe representation of
predictions.
- class zensols.lmtask.test.Tester(source, task, result_file, prediction_col='prediction', raw_col=None, result_mapper=<function Tester.<lambda>>, limit=None)[source]¶
Bases:
DictableTests the fit of the model on a dataset.
- __init__(source, task, result_file, prediction_col='prediction', raw_col=None, result_mapper=<function Tester.<lambda>>, limit=None)¶
-
result_file:
Path¶ The file to save the training statistics for benchmarking.
- result_mapper()¶
Map the result by calling with the single
task.TaskResponse.
-
source:
TaskDatasetFactory¶ A factory that creates new datasets used to evaluation.
zensols.lmtask.torchconfig module¶
CUDA access and utility module.
Copied from zensols.deeplearn, which is a heavy dependency package.
Remove this module if that dependency is ever added.
- class zensols.lmtask.torchconfig.CudaInfo[source]¶
Bases:
WritableA utility class that provides information about the CUDA configuration for the current (hardware) environment.
- class zensols.lmtask.torchconfig.TorchConfig(use_gpu=True, data_type=torch.float32, cuda_device_index=None, device_name=None)[source]¶
Bases:
PersistableContainer,WritableA utility class that provides access to CUDA APIs. It provides information on the current CUDA configuration and convenience methods to create, copy and modify tensors. These are handy for any given CUDA configuration and can back off to the CPU when CUDA isn’t available.
- __init__(use_gpu=True, data_type=torch.float32, cuda_device_index=None, device_name=None)[source]¶
Initialize this configuration.
- Parameters:
use_gpu (
bool) – whether or not to use CUDA/GPUdata_type (
type) – the default data type to use when creating new tensors in this configurationcuda_device_index (
int) – the CUDA device to use, which defaults to 0 if CUDA ifuse_gpuisTruedevice_name (
str) – the string name of the device to use (i.e.cpuormps); if provided, overridescuda_device_index
- cat(*args, **kwargs)[source]¶
Concatenate tensors in to one tensor using
torch.cat.- Return type:
Tensor
- static close(a, b)[source]¶
Return whether or not two tensors are equal. This does an exact cell comparison.
- Return type:
- property cpu_device: torch.device¶
Return the CPU CUDA device, which is the device type configured to utilize the CPU (rather than the GPU).
- cross_entropy_pad(size)[source]¶
Create a padded tensor of size
sizeusing the repeated padignore_index.- Return type:
Tensor
- property cuda_configs: tuple[TorchConfig, ...]¶
Return a new set of configurations, one for each CUDA device.
- property cuda_device_index: int | None¶
Return the CUDA device index if CUDA is being used for this configuration. Otherwise return
None.
- property device: device¶
Return the torch device configured.
- static empty_cache()[source]¶
Empty the CUDA torch cache. This releases memory in the GPU and should not be necessary to call for normal use cases.
- static equal(a, b)[source]¶
Return whether or not two tensors are equal. This does an exact cell comparison.
- Return type:
- float(*args, **kwargs)[source]¶
Return a new tensor using
torch.tensoras a float type.- Return type:
Tensor
- property float_type: type¶
Return the float type that represents this configuration, converting to the corresponding precision from integer if necessary.
- Returns:
the float that represents this data, or
Noneif neither float nor int
- from_iterable(array)[source]¶
Return a one dimenstional tensor created from
arrayusing the type and device in the current instance configuration.- Return type:
Tensor
- from_numpy(arr)[source]¶
Return a new tensor generated from a numpy aray using
torch.from_numpy. The array type is converted if necessary.- Return type:
Tensor
- get_peak_memory(format=False)[source]¶
Return peak allocated and reserved CUDA memory for visible devices.
- classmethod get_random_seed()[source]¶
Get the cross system random seed, meaning the seed applied to CUDA and the Python random library.
- Return type:
- classmethod get_random_seed_context()[source]¶
Return the random seed context given to
set_random_seed()to restore across models for consistent results.
- static in_memory_tensors()[source]¶
Returns all in-memory tensors and parameters.
- See:
show_leaks()- Return type:
list[Tensor]
- classmethod init(spawn_multiproc='spawn', seed_kwargs={})[source]¶
Initialize the PyTorch framework. This includes:
Configuration of PyTorch multiprocessing so subprocesses can access the GPU, and
Setting the random seed state.
The needs to be initialized at the very beginning of your program if you are training a new model. Note: this should be called when testing a model, but not when inferencing a production model.
Example:
def main(): from zensols.deeplearn import TorchConfig TorchConfig.init()
Note: this method is separate from
set_random_seed()because that method is called by the framework to reset the seed after a model is unpickled.- See:
torch.multiprocessing- See:
- int(*args, **kwargs)[source]¶
Return a new tensor using
torch.tensoras a int type.- Return type:
Tensor
- property int_type: type¶
Return the int type that represents this configuration, converting to the corresponding precision from integer if necessary.
- Returns:
the int that represents this data, or
Noneif neither int nor float
- property numpy_data_type: type[dtype]¶
Return the numpy type that corresponds to this instance’s configured
data_type.
- same_device(tensor_or_model)[source]¶
Return whether or not a tensor or model is in the same memory space as this configuration instance.
- Return type:
- classmethod set_random_seed(seed=0, disable_cudnn=True, rng_state=True)[source]¶
Set the random number generator for PyTorch.
- Parameters:
- See:
- See:
- property tensor_class: type[dtype]¶
Return the class type based on the current configuration of this instance. For example, if using
torch.float32on the GPU,torch.cuda.FloatTensoris returned.
- to(tensor_or_model)[source]¶
Copy the tensor or model to the device this to that of this configuration.
- Return type:
Module|Tensor
- classmethod to_cpu_deallocate(*arrs)[source]¶
Safely copy detached memory to the CPU and delete local instance (possibly GPU) memory to speed up resource deallocation. If the tensor is already on the CPU, it’s simply passed back. Otherwise the tensor is deleted.
This method is robust with
None, which are skipped and substituted asNonein the output.
- to_type(arr)[source]¶
Convert the type of the given array to the type of this instance.
- Return type:
Tensor
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
Write the contents of this instance to
writerusing indentiondepth.- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- write_device_tensors(writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
Like
write_in_memory_tensors(), but filter on this instance’s device.- Parameters:
filter_device – if given, write only tensors matching this device
- See:
TorchConfig
- class zensols.lmtask.torchconfig.printopts(**kwargs)[source]¶
Bases:
objectObject used with a
withscope that sets options, then sets them back.Example:
with printopts(profile='full', linewidth=120): print(tensor)
- DEFAULTS = {'edgeitems': 3, 'linewidth': 80, 'precision': 4, 'profile': 'default', 'sci_mode': None, 'threshold': 1000}¶
zensols.lmtask.torchtype module¶
CUDA access and utility module.
- class zensols.lmtask.torchtype.TorchTypes[source]¶
Bases:
objectA utility class to convert betwen numpy and torch classes. It also provides metadata for types that make other conversions, such as same precision cross types (i.e. int64 -> float64).
- FLOAT_TO_INT = {torch.float16: torch.int16, torch.float32: torch.int32, torch.float64: torch.int64}¶
- FLOAT_TYPES = frozenset({torch.float16, torch.float32, torch.float64})¶
- INT_TO_FLOAT = {torch.int16: torch.float16, torch.int32: torch.float32, torch.int64: torch.float64}¶
- INT_TYPES = frozenset({torch.int16, torch.int32, torch.int64})¶
- NAME_TO_TYPE = {'bool': {'cpu': <class 'torch.BoolTensor'>, 'desc': 'Boolean', 'gpu': <class 'torch.cuda.BoolTensor'>, 'name': 'bool', 'numpy': <class 'bool'>, 'types': {torch.bool}}, 'float16': {'cpu': <class 'torch.HalfTensor'>, 'desc': '16-bit floating point', 'gpu': <class 'torch.cuda.HalfTensor'>, 'name': 'float16', 'numpy': <class 'numpy.float16'>, 'sparse': <class 'torch.sparse.HalfTensor'>, 'types': {torch.float16}}, 'float32': {'cpu': <class 'torch.FloatTensor'>, 'desc': '32-bit floating point', 'gpu': <class 'torch.cuda.FloatTensor'>, 'name': 'float32', 'numpy': <class 'numpy.float32'>, 'sparse': <class 'torch.sparse.FloatTensor'>, 'types': {torch.float32}}, 'float64': {'cpu': <class 'torch.DoubleTensor'>, 'desc': '64-bit floating point', 'gpu': <class 'torch.cuda.DoubleTensor'>, 'name': 'float64', 'numpy': <class 'numpy.float64'>, 'sparse': <class 'torch.sparse.DoubleTensor'>, 'types': {torch.float64}}, 'int16': {'cpu': <class 'torch.ShortTensor'>, 'desc': '16-bit integer (signed)', 'gpu': <class 'torch.cuda.ShortTensor'>, 'name': 'int16', 'numpy': <class 'numpy.int16'>, 'sparse': <class 'torch.sparse.ShortTensor'>, 'types': {torch.int16}}, 'int32': {'cpu': <class 'torch.IntTensor'>, 'desc': '32-bit integer (signed)', 'gpu': <class 'torch.cuda.IntTensor'>, 'name': 'int32', 'numpy': <class 'numpy.int32'>, 'sparse': <class 'torch.sparse.IntTensor'>, 'types': {torch.int32}}, 'int64': {'cpu': <class 'torch.LongTensor'>, 'desc': '64-bit integer (signed)', 'gpu': <class 'torch.cuda.LongTensor'>, 'name': 'int64', 'numpy': <class 'numpy.int64'>, 'sparse': <class 'torch.sparse.LongTensor'>, 'types': {torch.int64}}, 'int8': {'cpu': <class 'torch.CharTensor'>, 'desc': '8-bit integer (signed)', 'gpu': <class 'torch.cuda.CharTensor'>, 'name': 'int8', 'numpy': <class 'numpy.int8'>, 'sparse': <class 'torch.sparse.CharTensor'>, 'types': {torch.int8}}, 'uint8': {'cpu': <class 'torch.ByteTensor'>, 'desc': '8-bit integer (unsigned)', 'gpu': <class 'torch.cuda.ByteTensor'>, 'name': 'uint8', 'numpy': <class 'numpy.uint8'>, 'sparse': <class 'torch.sparse.ByteTensor'>, 'types': {torch.uint8}}}¶
A map of type to metadata.
- TYPES = [{'cpu': <class 'torch.FloatTensor'>, 'desc': '32-bit floating point', 'gpu': <class 'torch.cuda.FloatTensor'>, 'name': 'float32', 'numpy': <class 'numpy.float32'>, 'sparse': <class 'torch.sparse.FloatTensor'>, 'types': {torch.float32}}, {'cpu': <class 'torch.DoubleTensor'>, 'desc': '64-bit floating point', 'gpu': <class 'torch.cuda.DoubleTensor'>, 'name': 'float64', 'numpy': <class 'numpy.float64'>, 'sparse': <class 'torch.sparse.DoubleTensor'>, 'types': {torch.float64}}, {'cpu': <class 'torch.HalfTensor'>, 'desc': '16-bit floating point', 'gpu': <class 'torch.cuda.HalfTensor'>, 'name': 'float16', 'numpy': <class 'numpy.float16'>, 'sparse': <class 'torch.sparse.HalfTensor'>, 'types': {torch.float16}}, {'cpu': <class 'torch.ByteTensor'>, 'desc': '8-bit integer (unsigned)', 'gpu': <class 'torch.cuda.ByteTensor'>, 'name': 'uint8', 'numpy': <class 'numpy.uint8'>, 'sparse': <class 'torch.sparse.ByteTensor'>, 'types': {torch.uint8}}, {'cpu': <class 'torch.CharTensor'>, 'desc': '8-bit integer (signed)', 'gpu': <class 'torch.cuda.CharTensor'>, 'name': 'int8', 'numpy': <class 'numpy.int8'>, 'sparse': <class 'torch.sparse.CharTensor'>, 'types': {torch.int8}}, {'cpu': <class 'torch.ShortTensor'>, 'desc': '16-bit integer (signed)', 'gpu': <class 'torch.cuda.ShortTensor'>, 'name': 'int16', 'numpy': <class 'numpy.int16'>, 'sparse': <class 'torch.sparse.ShortTensor'>, 'types': {torch.int16}}, {'cpu': <class 'torch.IntTensor'>, 'desc': '32-bit integer (signed)', 'gpu': <class 'torch.cuda.IntTensor'>, 'name': 'int32', 'numpy': <class 'numpy.int32'>, 'sparse': <class 'torch.sparse.IntTensor'>, 'types': {torch.int32}}, {'cpu': <class 'torch.LongTensor'>, 'desc': '64-bit integer (signed)', 'gpu': <class 'torch.cuda.LongTensor'>, 'name': 'int64', 'numpy': <class 'numpy.int64'>, 'sparse': <class 'torch.sparse.LongTensor'>, 'types': {torch.int64}}, {'cpu': <class 'torch.BoolTensor'>, 'desc': 'Boolean', 'gpu': <class 'torch.cuda.BoolTensor'>, 'name': 'bool', 'numpy': <class 'bool'>, 'types': {torch.bool}}]¶
A list of dicts containig conversions between types.
zensols.lmtask.train module¶
Continued Pretraining and supervised fine-tuning training.
- exception zensols.lmtask.train.TrainError[source]¶
Bases:
APIError- __annotations__ = {}¶
- __firstlineno__ = 29¶
- __module__ = 'zensols.lmtask.train'¶
- __static_attributes__ = ()¶
- class zensols.lmtask.train.TrainResult(train_output, peft_output_dir, train_params, config, time_elapsed)[source]¶
Bases:
DictableThe trained model config, location and configuration used to train it.
- __init__(train_output, peft_output_dir, train_params, config, time_elapsed)¶
-
config:
Configurable¶ The application configuration used to configure the trainer.
- property global_step: int¶
The global step from
train_output.
- property metrics: dict[str, float]¶
Training metrics from
train_output.
-
peft_output_dir:
Path¶ The directory of the models checkpoints.
-
train_output:
TrainOutput¶ The output returned from the trainer.
- property training_loss: float¶
The training loss from
train_output.
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, include_training_arguments=False, include_config=False)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- class zensols.lmtask.train.Trainer(config, resource, train_params, eval_params, train_source, eval_source, peft_output_dir, result_file)[source]¶
Bases:
DictableA configurable supervised fine-tuning trainer wrapper.
- __init__(config, resource, train_params, eval_params, train_source, eval_source, peft_output_dir, result_file)¶
-
config:
Configurable¶ Used to save to the model result.
-
eval_source:
TaskDatasetFactory¶ A factory that creates new datasets used to evaluation.
-
peft_output_dir:
Path¶ The directory in which to save the PEFT adapter.
-
resource:
TrainerResource¶ Used to create the model and tokenizer.
-
result_file:
Path¶ The file to save the training statistics for benchmarking.
-
train_source:
TaskDatasetFactory¶ A factory that creates new datasets used to train using this instance.
- write(depth=0, writer=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, include_training_arguments=False)[source]¶
Write this instance as either a
Writableor as aDictable. If class attribute_DICTABLE_WRITABLE_DESCENDANTSis set asTrue, then use thewrite()method on children instead of writing the generated dictionary. Otherwise, write this instance by first creating adictrecursively usingasdict(), then formatting the output.If the attribute
_DICTABLE_WRITE_EXCLUDESis set, those attributes are removed from what is written in thewrite()method.Note that this attribute will need to be set in all descendants in the instance hierarchy since writing the object instance graph is done recursively.
- Parameters:
depth (
int) – the starting indentation depthwriter (
TextIOBase) – the writer to dump the content of this writable
- class zensols.lmtask.train.TrainerResource(model_args=None, cache=True)[source]¶
-
Configures and instantiates the base mode, PEFT mode, and the tokenizer.
- __init__(model_args=None, cache=True)¶
- property model: PreTrainedModel¶
The base model.
- property peft_model: PeftModelForCausalLM¶
The PEFT (Parameter-Efficient Fine-Tuning) such as LoRA.
- property tokenizer: PythonBackend¶
The base tokenizer.