Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added convert_from_recipe script #1568

Merged
merged 15 commits into from
Oct 30, 2023
Merged

Conversation

BloodAxe
Copy link
Collaborator

@BloodAxe BloodAxe commented Oct 24, 2023

This PR adds convert_from_recipe entry point to create self-contained script to train a model with given recipe.
Generate script file contains full config paramteres to train the model.

Example usage:

General use: python -m super_gradients.convert_recipe_to_code --config-name="DESIRED_RECIPE".

How it works

  1. We compose the recipe config using hydra.compose but we do no instantiate objects using hydra.
  2. We traverse config recursively to identify places, where hydra instantiation takes place
  3. We replace hydra instantiation with variable references & instantiate those variables in generated code. This is the most tricky part of the script.
  4. We run black formatter on generated content file to make it look pretty and dump to output file

Open questions

  1. Generated config is pretty verbose (expected). Should we somehow attempt to "shrink" it and drop properties whose values are the default ones?
  2. I'm not particularly proud how _lr_updates = super_gradients.training.utils.utils.empty_list() looks like. Fixing such special cases would require adding if checks for each such special case.
  3. How should we test this. Would a test that runs over all existing recipes and exporting them work?

Example of the generated script file:

import super_gradients
from super_gradients import init_trainer, Trainer
from super_gradients.training.utils.distributed_training_utils import setup_device
from super_gradients.training import models, dataloaders
from super_gradients.common.data_types.enum import MultiGPUMode, StrictLoad
import numpy as np


def main():
    init_trainer()
    setup_device(device=None, multi_gpu="DDP", num_gpus=8)

    trainer = Trainer(experiment_name="coco2017_yolo_nas_s", ckpt_root_dir="None")

    num_classes = 80
    arch_params = {
        "in_channels": 3,
        "backbone": {
            "NStageBackbone": {
                "stem": {"YoloNASStem": {"out_channels": 48}},
                "stages": [
                    {"YoloNASStage": {"out_channels": 96, "num_blocks": 2, "activation_type": "relu", "hidden_channels": 32, "concat_intermediates": False}},
                    {"YoloNASStage": {"out_channels": 192, "num_blocks": 3, "activation_type": "relu", "hidden_channels": 64, "concat_intermediates": False}},
                    {"YoloNASStage": {"out_channels": 384, "num_blocks": 5, "activation_type": "relu", "hidden_channels": 96, "concat_intermediates": False}},
                    {"YoloNASStage": {"out_channels": 768, "num_blocks": 2, "activation_type": "relu", "hidden_channels": 192, "concat_intermediates": False}},
                ],
                "context_module": {"SPP": {"output_channels": 768, "activation_type": "relu", "k": [5, 9, 13]}},
                "out_layers": ["stage1", "stage2", "stage3", "context_module"],
            }
        },
        "neck": {
            "YoloNASPANNeckWithC2": {
                "neck1": {
                    "YoloNASUpStage": {
                        "out_channels": 192,
                        "num_blocks": 2,
                        "hidden_channels": 64,
                        "width_mult": 1,
                        "depth_mult": 1,
                        "activation_type": "relu",
                        "reduce_channels": True,
                    }
                },
                "neck2": {
                    "YoloNASUpStage": {
                        "out_channels": 96,
                        "num_blocks": 2,
                        "hidden_channels": 48,
                        "width_mult": 1,
                        "depth_mult": 1,
                        "activation_type": "relu",
                        "reduce_channels": True,
                    }
                },
                "neck3": {
                    "YoloNASDownStage": {
                        "out_channels": 192,
                        "num_blocks": 2,
                        "hidden_channels": 64,
                        "activation_type": "relu",
                        "width_mult": 1,
                        "depth_mult": 1,
                    }
                },
                "neck4": {
                    "YoloNASDownStage": {
                        "out_channels": 384,
                        "num_blocks": 2,
                        "hidden_channels": 64,
                        "activation_type": "relu",
                        "width_mult": 1,
                        "depth_mult": 1,
                    }
                },
            }
        },
        "heads": {
            "NDFLHeads": {
                "num_classes": 80,
                "reg_max": 16,
                "heads_list": [
                    {"YoloNASDFLHead": {"inter_channels": 128, "width_mult": 0.5, "first_conv_group_size": 0, "stride": 8}},
                    {"YoloNASDFLHead": {"inter_channels": 256, "width_mult": 0.5, "first_conv_group_size": 0, "stride": 16}},
                    {"YoloNASDFLHead": {"inter_channels": 512, "width_mult": 0.5, "first_conv_group_size": 0, "stride": 32}},
                ],
            }
        },
        "bn_eps": 0.001,
        "bn_momentum": 0.03,
        "inplace_act": True,
        "_convert_": "all",
        "num_classes": 80,
    }

    model = models.get(
        model_name="yolo_nas_s",
        num_classes=num_classes,
        arch_params=arch_params,
        strict_load=StrictLoad.NO_KEY_MATCHING,
        pretrained_weights=None,
        checkpoint_path=None,
        load_backbone=False,
        checkpoint_num_classes=None,
    )

    train_dataloader = dataloaders.get(
        name="coco2017_train_yolo_nas",
        dataset_params={
            "data_dir": "/data/coco",
            "subdir": "images/train2017",
            "json_file": "instances_train2017.json",
            "input_dim": [640, 640],
            "cache_dir": None,
            "cache": False,
            "cache_annotations": True,
            "ignore_empty_annotations": True,
            "transforms": [
                {
                    "DetectionRandomAffine": {
                        "degrees": 0,
                        "translate": 0.25,
                        "scales": [0.5, 1.5],
                        "shear": 0.0,
                        "target_size": None,
                        "filter_box_candidates": True,
                        "wh_thr": 2,
                        "area_thr": 0.1,
                        "ar_thr": 20,
                    }
                },
                {"DetectionRGB2BGR": {"prob": 0.5}},
                {"DetectionHSV": {"prob": 0.5, "hgain": 18, "sgain": 30, "vgain": 30}},
                {"DetectionHorizontalFlip": {"prob": 0.5}},
                {"DetectionMixup": {"input_dim": None, "mixup_scale": [0.5, 1.5], "prob": 0.5, "flip_prob": 0.5}},
                {"DetectionPaddedRescale": {"input_dim": [640, 640], "pad_value": 114}},
                {"DetectionStandardize": {"max_value": 255.0}},
                {"DetectionTargetsFormatTransform": {"output_format": "LABEL_CXCYWH"}},
            ],
            "tight_box_rotation": False,
            "class_inclusion_list": None,
            "max_num_samples": None,
            "with_crowd": False,
        },
        dataloader_params={"batch_size": 32, "num_workers": 8, "shuffle": True, "drop_last": True, "pin_memory": True, "collate_fn": "DetectionCollateFN"},
    )

    val_dataloader = dataloaders.get(
        name="coco2017_val_yolo_nas",
        dataset_params={
            "data_dir": "/data/coco",
            "subdir": "images/val2017",
            "json_file": "instances_val2017.json",
            "input_dim": [636, 636],
            "cache_dir": None,
            "cache": False,
            "cache_annotations": True,
            "ignore_empty_annotations": True,
            "transforms": [
                {"DetectionRGB2BGR": {"prob": 1}},
                {"DetectionPadToSize": {"output_size": [640, 640], "pad_value": 114}},
                {"DetectionStandardize": {"max_value": 255.0}},
                "DetectionImagePermute",
                {"DetectionTargetsFormatTransform": {"input_dim": [640, 640], "output_format": "LABEL_CXCYWH"}},
            ],
            "tight_box_rotation": False,
            "class_inclusion_list": None,
            "max_num_samples": None,
            "with_crowd": True,
        },
        dataloader_params={
            "batch_size": 25,
            "num_workers": 8,
            "drop_last": False,
            "shuffle": False,
            "pin_memory": True,
            "collate_fn": "CrowdDetectionCollateFN",
        },
    )

    _lr_updates = super_gradients.training.utils.utils.empty_list()

    _valid_metrics_list_0_detectionmetrics_post_prediction_callback = super_gradients.training.models.detection_models.pp_yolo_e.PPYoloEPostPredictionCallback(
        score_threshold=0.01, nms_top_k=1000, max_predictions=300, nms_threshold=0.7
    )

    training_hyperparams = {
        "resume": None,
        "run_id": None,
        "resume_path": None,
        "resume_from_remote_sg_logger": False,
        "ckpt_name": "ckpt_latest.pth",
        "lr_mode": "CosineLRScheduler",
        "lr_schedule_function": None,
        "lr_warmup_epochs": 0,
        "lr_warmup_steps": 1000,
        "lr_cooldown_epochs": 0,
        "warmup_initial_lr": 1e-06,
        "step_lr_update_freq": None,
        "cosine_final_lr_ratio": 0.1,
        "warmup_mode": "LinearBatchLRWarmup",
        "lr_updates": _lr_updates,
        "pre_prediction_callback": None,
        "optimizer": "AdamW",
        "optimizer_params": {"weight_decay": 1e-05},
        "load_opt_params": True,
        "zero_weight_decay_on_bias_and_bn": True,
        "loss": {"PPYoloELoss": {"use_static_assigner": False, "num_classes": 80, "reg_max": 16}},
        "criterion_params": {},
        "ema": True,
        "ema_params": {"decay": 0.9997, "decay_type": "threshold", "beta": 15},
        "train_metrics_list": [],
        "valid_metrics_list": [
            {
                "DetectionMetrics": {
                    "score_thres": 0.1,
                    "top_k_predictions": 300,
                    "num_cls": 80,
                    "normalize_targets": True,
                    "post_prediction_callback": _valid_metrics_list_0_detectionmetrics_post_prediction_callback,
                }
            }
        ],
        "metric_to_watch": "mAP@0.50:0.95",
        "greater_metric_to_watch_is_better": True,
        "launch_tensorboard": False,
        "tensorboard_port": None,
        "tb_files_user_prompt": False,
        "save_tensorboard_to_s3": False,
        "precise_bn": False,
        "precise_bn_batch_size": None,
        "sync_bn": True,
        "silent_mode": False,
        "mixed_precision": True,
        "save_ckpt_epoch_list": [100, 200, 250],
        "average_best_models": True,
        "dataset_statistics": False,
        "batch_accumulate": 1,
        "run_validation_freq": 1,
        "run_test_freq": 1,
        "save_model": True,
        "seed": 42,
        "phase_callbacks": [],
        "log_installed_packages": True,
        "clip_grad_norm": None,
        "ckpt_best_name": "ckpt_best.pth",
        "max_train_batches": None,
        "max_valid_batches": None,
        "sg_logger": "base_sg_logger",
        "sg_logger_params": {
            "tb_files_user_prompt": False,
            "launch_tensorboard": False,
            "tensorboard_port": None,
            "save_checkpoints_remote": False,
            "save_tensorboard_remote": False,
            "save_logs_remote": False,
            "monitor_system": True,
        },
        "torch_compile": False,
        "torch_compile_loss": False,
        "torch_compile_options": {"mode": "reduce-overhead", "fullgraph": False, "dynamic": False, "backend": "inductor", "options": None, "disable": False},
        "_convert_": "all",
        "max_epochs": 300,
        "initial_lr": 0.0002,
    }

    # TRAIN
    result = trainer.train(
        model=model,
        train_loader=train_dataloader,
        valid_loader=val_dataloader,
        training_params=training_hyperparams,
    )

    print(result)


if __name__ == "__main__":
    main()

src/super_gradients/convert_from_recipe.py Outdated Show resolved Hide resolved
src/super_gradients/convert_from_recipe.py Outdated Show resolved Hide resolved
src/super_gradients/convert_from_recipe.py Outdated Show resolved Hide resolved
src/super_gradients/convert_from_recipe.py Outdated Show resolved Hide resolved
src/super_gradients/convert_from_recipe.py Outdated Show resolved Hide resolved
src/super_gradients/convert_from_recipe.py Outdated Show resolved Hide resolved
@BloodAxe BloodAxe marked this pull request as ready for review October 25, 2023 10:57
# Conflicts:
#	tests/deci_core_unit_test_suite_runner.py
@shaydeci
Copy link
Collaborator

This PR adds convert_from_recipe entry point to create self-contained script to train a model with given recipe. Generate script file contains full config paramteres to train the model.

Example usage:

General use: python -m super_gradients.convert_from_recipe --config-name="DESIRED_RECIPE".

How it works

  1. We compose the recipe config using hydra.compose but we do no instantiate objects using hydra.
  2. We traverse config recursively to identify places, where hydra instantiation takes place
  3. We replace hydra instantiation with variable references & instantiate those variables in generated code. This is the most tricky part of the script.
  4. We run black formatter on generated content file to make it look pretty and dump to output file

Open questions

  1. Generated config is pretty verbose (expected). Should we somehow attempt to "shrink" it and drop properties whose values are the default ones?
  2. I'm not particularly proud how _lr_updates = super_gradients.training.utils.utils.empty_list() looks like. Fixing such special cases would require adding if checks for each such special case.
  3. How should we test this. Would a test that runs over all existing recipes and exporting them work?

Example of the generated script file:

import super_gradients
from super_gradients import init_trainer, Trainer
from super_gradients.training.utils.distributed_training_utils import setup_device
from super_gradients.training import models, dataloaders
from super_gradients.common.data_types.enum import MultiGPUMode, StrictLoad
import numpy as np


def main():
    init_trainer()
    setup_device(device=None, multi_gpu="DDP", num_gpus=8)

    trainer = Trainer(experiment_name="coco2017_pose_dekr_w32_no_dc", ckpt_root_dir="None")

    num_classes = 17
    arch_params = {
        "SPEC": {
            "FINAL_CONV_KERNEL": 1,
            "STAGES": {
                "NUM_STAGES": 3,
                "NUM_MODULES": [1, 4, 3],
                "NUM_BRANCHES": [2, 3, 4],
                "BLOCK": ["BASIC", "BASIC", "BASIC"],
                "NUM_BLOCKS": [[4, 4], [4, 4, 4], [4, 4, 4, 4]],
                "NUM_CHANNELS": [[32, 64], [32, 64, 128], [32, 64, 128, 256]],
                "FUSE_METHOD": ["SUM", "SUM", "SUM"],
            },
            "HEAD_HEATMAP": {
                "BLOCK": "BASIC",
                "NUM_BLOCKS": 1,
                "NUM_CHANNELS": 32,
                "DILATION_RATE": 1,
                "HEATMAP_APPLY_SIGMOID": False,
            },
            "HEAD_OFFSET": {"BLOCK": "BASIC", "DILATION_RATE": 5, "NUM_BLOCKS": 2, "NUM_CHANNELS_PERKPT": 15},
        },
        "num_classes": 17,
    }

    model = models.get(
        model_name="dekr_w32_no_dc",
        num_classes=num_classes,
        arch_params=arch_params,
        strict_load=StrictLoad.KEY_MATCHING,
        pretrained_weights=None,
        checkpoint_path=None,
        load_backbone=False,
        checkpoint_num_classes=None,
    )

    train_dataloader = dataloaders.get(
        name="coco2017_pose_train",
        dataset_params={
            "data_dir": "/data/coco",
            "images_dir": "images/train2017",
            "json_file": "annotations/person_keypoints_train2017.json",
            "include_empty_samples": False,
            "min_instance_area": 64,
            "edge_links": [
                [0, 1],
                [0, 2],
                [1, 2],
                [1, 3],
                [2, 4],
                [3, 5],
                [4, 6],
                [5, 6],
                [5, 7],
                [5, 11],
                [6, 8],
                [6, 12],
                [7, 9],
                [8, 10],
                [11, 12],
                [11, 13],
                [12, 14],
                [13, 15],
                [14, 16],
            ],
            "edge_colors": [
                [214, 39, 40],
                [148, 103, 189],
                [44, 160, 44],
                [140, 86, 75],
                [227, 119, 194],
                [127, 127, 127],
                [188, 189, 34],
                [127, 127, 127],
                [188, 189, 34],
                [140, 86, 75],
                [23, 190, 207],
                [227, 119, 194],
                [31, 119, 180],
                [255, 127, 14],
                [148, 103, 189],
                [255, 127, 14],
                [214, 39, 40],
                [31, 119, 180],
                [44, 160, 44],
            ],
            "keypoint_colors": [
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
            ],
            "transforms": [
                {"KeypointsLongestMaxSize": {"max_height": 640, "max_width": 640}},
                {
                    "KeypointsPadIfNeeded": {
                        "min_height": 640,
                        "min_width": 640,
                        "image_pad_value": 127,
                        "mask_pad_value": 1,
                    }
                },
                {
                    "KeypointsRandomHorizontalFlip": {
                        "flip_index": [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15],
                        "prob": 0.5,
                    }
                },
                {
                    "KeypointsRandomAffineTransform": {
                        "max_rotation": 30,
                        "min_scale": 0.5,
                        "max_scale": 2,
                        "max_translate": 0.2,
                        "image_pad_value": 127,
                        "mask_pad_value": 1,
                        "prob": 0.75,
                    }
                },
                {"KeypointsImageStandardize": {"max_value": 255}},
                {"KeypointsImageNormalize": {"mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225]}},
                "KeypointsImageToTensor",
            ],
            "target_generator": {
                "DEKRTargetsGenerator": {
                    "output_stride": 4,
                    "sigma": 2,
                    "center_sigma": 4,
                    "bg_weight": 0.1,
                    "offset_radius": 4,
                }
            },
        },
        dataloader_params={
            "shuffle": True,
            "batch_size": 24,
            "num_workers": 8,
            "drop_last": True,
            "collate_fn": "KeypointsCollate",
        },
    )

    val_dataloader = dataloaders.get(
        name="coco2017_pose_val",
        dataset_params={
            "data_dir": "/data/coco/",
            "images_dir": "images/val2017",
            "json_file": "annotations/person_keypoints_val2017.json",
            "include_empty_samples": True,
            "min_instance_area": 128,
            "edge_links": [
                [0, 1],
                [0, 2],
                [1, 2],
                [1, 3],
                [2, 4],
                [3, 5],
                [4, 6],
                [5, 6],
                [5, 7],
                [5, 11],
                [6, 8],
                [6, 12],
                [7, 9],
                [8, 10],
                [11, 12],
                [11, 13],
                [12, 14],
                [13, 15],
                [14, 16],
            ],
            "edge_colors": [
                [214, 39, 40],
                [148, 103, 189],
                [44, 160, 44],
                [140, 86, 75],
                [227, 119, 194],
                [127, 127, 127],
                [188, 189, 34],
                [127, 127, 127],
                [188, 189, 34],
                [140, 86, 75],
                [23, 190, 207],
                [227, 119, 194],
                [31, 119, 180],
                [255, 127, 14],
                [148, 103, 189],
                [255, 127, 14],
                [214, 39, 40],
                [31, 119, 180],
                [44, 160, 44],
            ],
            "keypoint_colors": [
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
                [31, 119, 180],
                [148, 103, 189],
            ],
            "transforms": [
                {"KeypointsLongestMaxSize": {"max_height": 640, "max_width": 640}},
                {
                    "KeypointsPadIfNeeded": {
                        "min_height": 640,
                        "min_width": 640,
                        "image_pad_value": 127,
                        "mask_pad_value": 1,
                    }
                },
                {"KeypointsImageStandardize": {"max_value": 255}},
                {"KeypointsImageNormalize": {"mean": [0.485, 0.456, 0.406], "std": [0.229, 0.224, 0.225]}},
                "KeypointsImageToTensor",
            ],
            "target_generator": {
                "DEKRTargetsGenerator": {
                    "output_stride": 4,
                    "sigma": 2,
                    "center_sigma": 4,
                    "bg_weight": 0.1,
                    "offset_radius": 4,
                }
            },
        },
        dataloader_params={"batch_size": 32, "num_workers": 8, "drop_last": False, "collate_fn": "KeypointsCollate"},
    )

    _lr_updates = super_gradients.training.utils.utils.empty_list()

    _valid_metrics_list_0_poseestimationmetrics_post_prediction_callback = (
        super_gradients.training.utils.pose_estimation.DEKRPoseEstimationDecodeCallback(
            max_num_people=30,
            keypoint_threshold=0.05,
            nms_threshold=0.05,
            nms_num_threshold=8,
            output_stride=4,
            apply_sigmoid=True,
        )
    )

    training_hyperparams = {
        "resume": False,
        "run_id": None,
        "resume_path": None,
        "resume_from_remote_sg_logger": False,
        "ckpt_name": "ckpt_latest.pth",
        "lr_mode": "CosineLRScheduler",
        "lr_schedule_function": None,
        "lr_warmup_epochs": 0,
        "lr_warmup_steps": 256,
        "lr_cooldown_epochs": 0,
        "warmup_initial_lr": 1e-06,
        "step_lr_update_freq": None,
        "cosine_final_lr_ratio": 0.1,
        "warmup_mode": "LinearEpochLRWarmup",
        "lr_updates": _lr_updates,
        "pre_prediction_callback": None,
        "optimizer": "AdamW",
        "optimizer_params": {"weight_decay": 0.0001},
        "load_opt_params": True,
        "zero_weight_decay_on_bias_and_bn": False,
        "loss": {"DEKRLoss": {"heatmap_loss": "qfl", "heatmap_loss_factor": 1.0, "offset_loss_factor": 0.1}},
        "criterion_params": {},
        "ema": False,
        "ema_params": {"decay": 0.9997, "decay_type": "exp", "beta": 20},
        "train_metrics_list": [],
        "valid_metrics_list": [
            {
                "PoseEstimationMetrics": {
                    "num_joints": 17,
                    "oks_sigmas": [
                        0.026,
                        0.025,
                        0.025,
                        0.035,
                        0.035,
                        0.079,
                        0.079,
                        0.072,
                        0.072,
                        0.062,
                        0.062,
                        0.107,
                        0.107,
                        0.087,
                        0.087,
                        0.089,
                        0.089,
                    ],
                    "max_objects_per_image": 30,
                    "post_prediction_callback": _valid_metrics_list_0_poseestimationmetrics_post_prediction_callback,
                }
            }
        ],
        "metric_to_watch": "AP",
        "greater_metric_to_watch_is_better": True,
        "launch_tensorboard": False,
        "tensorboard_port": None,
        "tb_files_user_prompt": False,
        "save_tensorboard_to_s3": False,
        "precise_bn": False,
        "precise_bn_batch_size": None,
        "sync_bn": False,
        "silent_mode": False,
        "mixed_precision": True,
        "save_ckpt_epoch_list": [],
        "average_best_models": True,
        "dataset_statistics": False,
        "batch_accumulate": 1,
        "run_validation_freq": 1,
        "run_test_freq": 1,
        "save_model": True,
        "seed": 42,
        "phase_callbacks": [],
        "log_installed_packages": True,
        "clip_grad_norm": None,
        "ckpt_best_name": "ckpt_best.pth",
        "max_train_batches": None,
        "max_valid_batches": None,
        "sg_logger": "base_sg_logger",
        "sg_logger_params": {
            "tb_files_user_prompt": False,
            "launch_tensorboard": False,
            "tensorboard_port": None,
            "save_checkpoints_remote": False,
            "save_tensorboard_remote": False,
            "save_logs_remote": False,
            "monitor_system": True,
        },
        "torch_compile": False,
        "torch_compile_loss": False,
        "torch_compile_options": {
            "mode": "reduce-overhead",
            "fullgraph": False,
            "dynamic": False,
            "backend": "inductor",
            "options": None,
            "disable": False,
        },
        "_convert_": "all",
        "max_epochs": 150,
        "initial_lr": 0.001,
    }

    # TRAIN
    result = trainer.train(
        model=model,
        train_loader=train_dataloader,
        valid_loader=val_dataloader,
        training_params=training_hyperparams,
    )

    print(result)


if __name__ == "__main__":
    main()

Also maybe find a better name?
We already have src/super_gradients/examples/convert_recipe_example/convert_recipe_example.py

@Louis-Dupont
Copy link
Contributor

Also maybe find a better name?
We already have src/super_gradients/examples/convert_recipe_example/convert_recipe_example.py

Maybe changing convert_from_recipe.py -> generate_script_from_recipe.py, generate_python_code_from_recipe.py or just recipe_to_code.py ?

@BloodAxe
Copy link
Collaborator Author

Recipe to code 🔥 🔥 🔥

shaydeci
shaydeci previously approved these changes Oct 30, 2023
Copy link
Collaborator

@shaydeci shaydeci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@shaydeci shaydeci merged commit ef8b54e into master Oct 30, 2023
7 checks passed
@shaydeci shaydeci deleted the feature/SG-1178-convert-from-recipe branch October 30, 2023 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants