What Is the Role of Pydantic in Soup CLI's Configuration?
Pydantic v2 provides Soup CLI with a declarative, strongly-typed configuration layer that validates soup.yaml files through hierarchical BaseModel schemas, ensuring type safety and domain-specific constraints before any training code executes.
Soup CLI, an open-source training framework hosted at MakazhanAlpamys/Soup, relies on Pydantic to manage its entire configuration pipeline. Instead of manual dictionary parsing, the CLI uses Pydantic v2 models to define, validate, and enforce the structure of user-defined settings stored in soup.yaml.
Declarative Schema Definition in schema.py
The file src/soup_cli/config/schema.py serves as the single source of truth for all configuration sections. Each component inherits from Pydantic's BaseModel:
- DataConfig handles dataset parameters
- TrainingConfig manages hyperparameters and quantization settings
- LoraConfig controls Low-Rank Adaptation options
This hierarchical inheritance creates a strongly-typed object graph. When nested models compose the top-level SoupConfig, the entire configuration tree becomes type-safe and self-documenting.
Automatic Type Coercion and Field Validation
When the CLI loads soup.yaml, it passes the raw dictionary to SoupConfig.model_validate(). Pydantic automatically:
- Coerces values to declared types (
int,float,Literal[...],Union[...]) - Enforces constraints defined via
Field()parameters such asge=0,le=1.0, andmax_length=4096 - Validates nested structures recursively through the model hierarchy
This eliminates boilerplate conversion code and ensures that downstream training modules receive properly typed values.
Custom Cross-Field Validation
Beyond type checking, Pydantic's @field_validator and @model_validator decorators enforce complex business rules. According to the source code in src/soup_cli/config/schema.py, these validators handle:
- Mutually exclusive LoRA methods (preventing simultaneous activation of incompatible options like
use_doraanduse_vera) - Stream-buffer consistency checks
- Exclusivity constraints between
train_on_responses_onlyandtrain_on_messages_with_train_field
These domain-specific validations run automatically during model instantiation, catching logical errors before training begins.
Fail-Fast Error Handling
If a user supplies an out-of-range value or an illegal combination, Pydantic raises a ValidationError with a clear, human-readable message. This fail-fast approach prevents obscure runtime crashes deep in the training loop. Instead of debugging GPU memory errors caused by invalid batch sizes, developers receive immediate feedback about which configuration key violated which constraint.
Lazy Dependency Management
The schema module intentionally imports only lightweight utilities, keeping validation isolated from heavy dependencies like torch and transformers. This architectural decision means:
- The CLI starts instantly even on systems without GPUs
- Configuration files can be validated and inspected without loading CUDA libraries
- Training dependencies are deferred until the validated config object actually reaches the training routine
The separation between src/soup_cli/config/schema.py and src/soup_cli/commands/run.py enforces this boundary.
Practical Configuration Loading
Here is how Soup CLI loads and validates a soup.yaml file:
from pathlib import Path
import yaml
from soup_cli.config.schema import SoupConfig
# Load raw YAML
yaml_path = Path("soup.yaml")
raw_cfg = yaml.safe_load(yaml_path.read_text())
# Pydantic validates and returns a strongly-typed config instance
config: SoupConfig = SoupConfig.model_validate(raw_cfg)
# Access validated fields with proper types
print("Training epochs:", config.training.epochs)
print("Quantization mode:", config.training.quantization)
Attempting to set mutually exclusive LoRA options triggers an immediate validation error:
# This raises ValidationError:
config.training.lora.use_dora = True
config.training.lora.use_vera = True # Mutually exclusive
Summary
- Pydantic provides the declarative foundation for Soup CLI's configuration system in
src/soup_cli/config/schema.py - BaseModel inheritance creates a hierarchical, strongly-typed schema covering
DataConfig,TrainingConfig, andLoraConfig - Automatic validation via
model_validate()enforces type coercion, field constraints, and custom business rules through@field_validatorand@model_validator - Fail-fast behavior ensures invalid configurations trigger clear
ValidationErrormessages before training code executes - Dependency isolation keeps the validation layer lightweight, avoiding heavy imports like
torchuntil absolutely necessary
Frequently Asked Questions
How does Soup CLI handle invalid configuration values?
Soup CLI uses Pydantic's validation engine to catch invalid values immediately upon loading soup.yaml. When SoupConfig.model_validate() encounters a type mismatch, constraint violation, or illegal parameter combination, it raises a ValidationError with a specific message indicating which field failed and why. This prevents the training process from starting with bad parameters.
Where are the Pydantic models for Soup CLI defined?
All Pydantic models reside in src/soup_cli/config/schema.py. This file defines the top-level SoupConfig class along with nested configuration sections like DataConfig, TrainingConfig, and LoraConfig. Each class inherits from Pydantic's BaseModel and uses Field() specifications to declare constraints and documentation.
Can I validate a Soup configuration without installing PyTorch?
Yes. The schema module is designed to import only lightweight standard library and utility modules, avoiding heavy dependencies like torch or transformers. This allows you to validate soup.yaml files and inspect configuration objects on any system, regardless of GPU availability or deep learning framework installation.
What types of cross-field validations does Soup CLI enforce?
According to the source code, validators enforce domain-specific rules such as mutual exclusivity between LoRA methods (e.g., preventing simultaneous use of use_dora and use_vera), consistency between streaming and buffer settings, and logical constraints between training modes like train_on_responses_only versus train_on_messages_with_train_field.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →