Download src/config/schema.py from InternsProgressUpdate/Venket: direct link, hf CLI and curl.
- Browser
- Download file 9.87 kB
-
https://huggingface.co/InternsProgressUpdate/Venket/resolve/main/src/config/schema.py
- Command line
-
hf download hf://InternsProgressUpdate/Venket/src/config/schema.py
-
curl -L -o schema.py https://huggingface.co/InternsProgressUpdate/Venket/resolve/main/src/config/schema.py
9.87 kB
| """Pydantic configuration schema for the synthetic document generation pipeline. | |
| Every user-facing parameter is validated here. Numeric placement/augmentation | |
| parameters accept either a fixed scalar or a ``{min, max}`` range (resolved | |
| per-sample by a seeded RNG, see :mod:`src.utils.random_utils`). | |
| The individual augmentation effects requested by the product spec are | |
| consolidated into configurable *families* where an effect is a strict | |
| specialization of another (paper stains + water stains -> ``stain`` with a | |
| ``type`` selector; edge/corner/fold shadows -> ``shadow`` with a ``type`` | |
| selector; crumpling + wrinkles -> ``crumple``; general discoloration + paper | |
| yellowing -> ``discoloration`` with a ``tone`` selector). This keeps the | |
| config surface coherent while still reaching every requested visual effect. | |
| """ | |
| from __future__ import annotations | |
| from typing import Literal, Union | |
| from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator | |
| NumericOrRange_T = Union[float, "Range"] | |
| class Range(BaseModel): | |
| """An inclusive ``[min, max]`` range a value is uniformly sampled from.""" | |
| model_config = ConfigDict(extra="forbid") | |
| min: float | |
| max: float | |
| def _check_order(self) -> "Range": | |
| if self.max < self.min: | |
| raise ValueError(f"Range max ({self.max}) must be >= min ({self.min})") | |
| return self | |
| NumericOrRange = Union[float, Range] | |
| class AugmentationParam(BaseModel): | |
| """Base schema shared by every augmentation effect. | |
| Extra keys are allowed so effect-specific parameters (e.g. ``type`` for | |
| :class:`ShadowParam`, ``tone`` for discoloration) can be declared inline | |
| in YAML without needing a bespoke subclass for every single effect. | |
| """ | |
| model_config = ConfigDict(extra="allow") | |
| enabled: bool = False | |
| strength: NumericOrRange = 0.0 | |
| probability: float = Field(default=1.0, ge=0.0, le=1.0) | |
| seed: "int | None" = None | |
| def _strength_bounds(cls, v: NumericOrRange) -> NumericOrRange: | |
| if isinstance(v, (int, float)) and not (0.0 <= float(v) <= 1.0): | |
| raise ValueError("strength must be within [0, 1]") | |
| return v | |
| class ShadowParam(AugmentationParam): | |
| type: Literal["edge", "corner", "fold", "random"] = "random" | |
| class StainParam(AugmentationParam): | |
| type: Literal["paper", "water", "random"] = "random" | |
| class DiscolorationParam(AugmentationParam): | |
| tone: Literal["yellow", "grey", "sepia", "random"] = "random" | |
| class CrumpleParam(AugmentationParam): | |
| wrinkle_density: NumericOrRange = 0.4 | |
| class JpegCompressionParam(AugmentationParam): | |
| min_quality: int = Field(default=35, ge=1, le=100) | |
| max_quality: int = Field(default=90, ge=1, le=100) | |
| class AugmentationsConfig(BaseModel): | |
| """The full family of configurable document/signature augmentations.""" | |
| model_config = ConfigDict(extra="forbid") | |
| rotation: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| stroke_dilation: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| motion_blur: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| gaussian_blur: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| perspective: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| scanner_noise: AugmentationParam = Field(default_factory=lambda: AugmentationParam(enabled=True, strength=0.06, probability=1.0)) | |
| salt_pepper: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| jpeg_compression: JpegCompressionParam = Field(default_factory=lambda: JpegCompressionParam()) | |
| contrast: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| gamma: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| coffee_stain: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| stain: StainParam = Field(default_factory=lambda: StainParam()) | |
| shadow: ShadowParam = Field(default_factory=lambda: ShadowParam()) | |
| crumple: CrumpleParam = Field(default_factory=lambda: CrumpleParam()) | |
| discoloration: DiscolorationParam = Field(default_factory=lambda: DiscolorationParam()) | |
| page_tilt: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| dust: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| scanner_streaks: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| ink_fading: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| ink_bleed: AugmentationParam = Field(default_factory=lambda: AugmentationParam()) | |
| def items(self): | |
| """Yield ``(name, AugmentationParam)`` pairs for every configured effect.""" | |
| for name in self.model_fields: | |
| yield name, getattr(self, name) | |
| class PlacementConfig(BaseModel): | |
| """Controls where and how the signature is positioned inside its target box.""" | |
| model_config = ConfigDict(extra="forbid") | |
| x_offset: NumericOrRange = 0.0 | |
| y_offset: NumericOrRange = 0.0 | |
| rotation_deg: NumericOrRange = 0.0 | |
| scale_factor: NumericOrRange = 0.9 | |
| anchor_point: Literal[ | |
| "center", "top_left", "top_right", "bottom_left", "bottom_right", | |
| "top_center", "bottom_center", "left_center", "right_center", | |
| ] = "center" | |
| margin: float = Field(default=0.06, ge=0.0, le=0.45) | |
| misplacement_probability: float = Field(default=0.0, ge=0.0, le=1.0) | |
| misplacement_strength: NumericOrRange = 0.3 | |
| allow_partial_outside: bool = False | |
| class RenderingConfig(BaseModel): | |
| """Controls how the signature layer is composited onto the document.""" | |
| model_config = ConfigDict(extra="forbid") | |
| blend_mode: Literal["multiply", "darken", "alpha"] = "multiply" | |
| ink_opacity: NumericOrRange = 0.88 | |
| blur_sigma: NumericOrRange = 0.35 | |
| feather_px: NumericOrRange = 1.2 | |
| scanner_noise: NumericOrRange = 0.02 | |
| anti_alias: bool = True | |
| class SignerConfig(BaseModel): | |
| """Optional overrides for the assigned signer identity.""" | |
| model_config = ConfigDict(extra="forbid") | |
| name: "str | None" = None | |
| role: "str | None" = None | |
| class SignatureSelectionConfig(BaseModel): | |
| """Controls how a signature image is drawn from the discovered dataset.""" | |
| model_config = ConfigDict(extra="forbid") | |
| source_filter: Literal["genuine", "forged", "any"] = "genuine" | |
| signature_id: "str | None" = None | |
| class DocumentConfig(BaseModel): | |
| """Selects which template (and page) to render.""" | |
| model_config = ConfigDict(extra="forbid") | |
| template: "str | None" = None | |
| page: "int | None" = None | |
| class QualityConfig(BaseModel): | |
| """Document quality-flag inputs (feed into the ``quality`` metadata block).""" | |
| model_config = ConfigDict(extra="forbid") | |
| case_type: "str | None" = None | |
| notes: "str | None" = None | |
| scanner_quality: NumericOrRange = 0.85 | |
| paper_quality: NumericOrRange = 0.85 | |
| render_quality: NumericOrRange = 0.85 | |
| class DifficultyWeights(BaseModel): | |
| """Weights and tier thresholds for the difficulty score. | |
| Defaults match the specification exactly: | |
| ``0.35*misplacement + 0.20*whitespace + 0.20*faintness + 0.15*smallness + 0.10*low_texture``. | |
| """ | |
| model_config = ConfigDict(extra="forbid") | |
| misplacement: float = 0.35 | |
| whitespace: float = 0.20 | |
| faintness: float = 0.20 | |
| smallness: float = 0.15 | |
| low_texture: float = 0.10 | |
| easy_threshold: float = 0.33 | |
| hard_threshold: float = 0.66 | |
| def _check_weights(self) -> "DifficultyWeights": | |
| total = self.misplacement + self.whitespace + self.faintness + self.smallness + self.low_texture | |
| if abs(total - 1.0) > 1e-6: | |
| raise ValueError(f"Difficulty weights must sum to 1.0, got {total}") | |
| return self | |
| class PathsConfig(BaseModel): | |
| """Filesystem locations for inputs/outputs.""" | |
| model_config = ConfigDict(extra="forbid") | |
| image_dir: str = "image" | |
| dataset_dir: str = "dataset" | |
| annotations_dir: str = "annotations" | |
| output_dir: str = "output" | |
| cache_dir: str = "output/.cache" | |
| class GenerationConfig(BaseModel): | |
| """Batch-generation controls.""" | |
| model_config = ConfigDict(extra="forbid") | |
| count: int = Field(default=10, ge=1) | |
| workers: int = Field(default=1, ge=1) | |
| save_visualization: bool = False | |
| overwrite: bool = False | |
| run_validation: bool = True | |
| start_index: int = Field(default=1, ge=0) | |
| filename_prefix: str = "sample" | |
| filename_digits: int = Field(default=6, ge=1) | |
| class ValidationConfig(BaseModel): | |
| """Controls strictness of the post-generation ValidationEngine.""" | |
| model_config = ConfigDict(extra="forbid") | |
| strict: bool = False | |
| max_coordinate_epsilon: float = 0.5 | |
| class PipelineConfig(BaseModel): | |
| """Top-level configuration for a full generation run.""" | |
| model_config = ConfigDict(extra="forbid") | |
| seed: int = 1234 | |
| paths: PathsConfig = Field(default_factory=PathsConfig) | |
| generation: GenerationConfig = Field(default_factory=GenerationConfig) | |
| document: DocumentConfig = Field(default_factory=DocumentConfig) | |
| signer: SignerConfig = Field(default_factory=SignerConfig) | |
| signature_selection: SignatureSelectionConfig = Field(default_factory=SignatureSelectionConfig) | |
| placement: PlacementConfig = Field(default_factory=PlacementConfig) | |
| rendering: RenderingConfig = Field(default_factory=RenderingConfig) | |
| augmentation: AugmentationsConfig = Field(default_factory=AugmentationsConfig) | |
| quality: QualityConfig = Field(default_factory=QualityConfig) | |
| difficulty: DifficultyWeights = Field(default_factory=DifficultyWeights) | |
| validation: ValidationConfig = Field(default_factory=ValidationConfig) | |