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:

  1. Coerces values to declared types (int, float, Literal[...], Union[...])
  2. Enforces constraints defined via Field() parameters such as ge=0, le=1.0, and max_length=4096
  3. 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_dora and use_vera)
  • Stream-buffer consistency checks
  • Exclusivity constraints between train_on_responses_only and train_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, and LoraConfig
  • Automatic validation via model_validate() enforces type coercion, field constraints, and custom business rules through @field_validator and @model_validator
  • Fail-fast behavior ensures invalid configurations trigger clear ValidationError messages before training code executes
  • Dependency isolation keeps the validation layer lightweight, avoiding heavy imports like torch until 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →