{"id":3324,"library":"yacs","title":"Yet Another Configuration System (YACS)","description":"YACS is a lightweight Python library for defining and managing system configurations, particularly useful in scientific experimentation for reproducibility. It provides a hierarchical CfgNode object for structured configuration and supports loading configurations from both Python files and YAML files. The current version is 0.1.8, with a relatively active release cadence.","status":"active","version":"0.1.8","language":"en","source_language":"en","source_url":"https://github.com/rbgirshick/yacs","tags":["configuration","config","yaml","deep-learning","reproducibility"],"install":[{"cmd":"pip install yacs","lang":"bash","label":"Install from PyPI"}],"dependencies":[{"reason":"Required for loading and dumping configurations from/to YAML files.","package":"PyYAML","optional":true}],"imports":[{"symbol":"CfgNode","correct":"from yacs.config import CfgNode as CN"}],"quickstart":{"code":"from yacs.config import CfgNode as CN\nimport os\n\n# 1. Define your default configuration in a Python file (e.g., config.py)\n_C = CN()\n\n_C.SYSTEM = CN()\n_C.SYSTEM.NUM_GPUS = 8\n_C.SYSTEM.NUM_WORKERS = 4\n\n_C.TRAIN = CN()\n_C.TRAIN.HYPERPARAMETER_1 = 0.1\n_C.TRAIN.SCALES = (2, 4, 8, 16)\n\ndef get_cfg_defaults():\n    \"\"\"Get a yacs CfgNode object with default values.\"\"\"\n    return _C.clone()\n\n# 2. Example usage in your main application\n# Simulate an experiment.yaml file\n# This content would typically be in a separate file\n# with only the overrides.\nexperiment_yaml_content = \"\"\"\nSYSTEM:\n  NUM_GPUS: 2\nTRAIN:\n  SCALES: (1, 2, 3, 4)\n\"\"\"\n\n# Create a dummy experiment.yaml for demonstration\nwith open(\"experiment.yaml\", \"w\") as f:\n    f.write(experiment_yaml_content)\n\n\nif __name__ == \"__main__\":\n    cfg = get_cfg_defaults()\n\n    # Merge from an experiment-specific YAML file\n    cfg.merge_from_file(\"experiment.yaml\")\n\n    # Override from a list of key-value pairs (e.g., from command line)\n    opts = [\"SYSTEM.NUM_GPUS\", 1, \"TRAIN.HYPERPARAMETER_1\", 0.5]\n    cfg.merge_from_list(opts)\n\n    # Freeze the configuration to prevent further modification\n    cfg.freeze()\n\n    print(\"Final Configuration:\")\n    print(cfg)\n    print(f\"Number of GPUs: {cfg.SYSTEM.NUM_GPUS}\")\n    print(f\"Training Hyperparameter 1: {cfg.TRAIN.HYPERPARAMETER_1}\")\n    print(f\"Training Scales: {cfg.TRAIN.SCALES}\")\n\n    # Clean up dummy file\n    os.remove(\"experiment.yaml\")\n","lang":"python","description":"This quickstart demonstrates how to define a default configuration using `CfgNode`, retrieve a mutable copy, and then merge overrides from a YAML file and a list of command-line style options. It also shows the recommended practice of freezing the configuration to ensure reproducibility."},"warnings":[{"fix":"Review existing configurations and code for usage of non-string keys. If present, ensure they are compatible with the new behavior or adapt them accordingly.","message":"Version 0.1.7 introduced explicit support for non-string keys in CfgNode. Prior to this, using non-string keys might have resulted in errors or implicit string conversion, which could be a breaking change for code that relied on or inadvertently used such keys.","severity":"breaking","affected_versions":"<0.1.7"},{"fix":"When using YACS, consolidate all command-line overrides through `cfg.merge_from_list(opts)` to maintain a single source of truth for configuration values. Avoid redundant argument parsing for values already managed by YACS.","message":"YACS promotes the principle of \"There is only one way to configure the same thing.\" It's a common footgun to use both YACS's `merge_from_list` for command-line overrides and separate `argparse` arguments for the same configuration options, leading to confusion or unexpected behavior.","severity":"gotcha","affected_versions":"All"},{"fix":"Always call `cfg.freeze()` on your primary configuration object once all modifications and merges are complete, typically at the start of your application logic.","message":"After loading and merging all configuration options, it's highly recommended to call `cfg.freeze()` to prevent accidental runtime modifications. Forgetting to freeze can lead to configurations changing unexpectedly during execution, hindering reproducibility.","severity":"gotcha","affected_versions":"All"},{"fix":"Verify your `pip install` commands and import statements (`from yacs.config import CfgNode`) to ensure you're using the correct configuration library.","message":"There are multiple Python projects named 'YACS' (e.g., for course scheduling or SALOME GUI). Ensure you are importing and using `yacs` from `github.com/rbgirshick/yacs` for the configuration system described here, as their functionalities are entirely distinct.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure that any Python configuration file intended for YACS loading exports a variable named `cfg` (e.g., `cfg = CN()` or `cfg = {'KEY': 'VALUE'}`) at the module level.","message":"When loading configurations from Python source files (`yacs>=0.1.4`), the module must export a global variable named `cfg` of type `dict` or `CfgNode`. Deviating from this convention will lead to import errors.","severity":"gotcha","affected_versions":">=0.1.4"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}