RepVGG Documentation

repository·main·Indexed 26 days ago

https://github.com/dingxiaoh/repvgg

Implementation of a VGG-style ConvNet architecture using structural re-parameterization to transition from complex multi-branch training structures to single-branch, high-throughput inference models. Includes support for RepVGGplus, tools for converting models to deploy mode via switch_to_deploy() or convert.py, and guides for Quantization-Aware Training (QAT) and fine-tuning for downstream tasks like semantic segmentation.

Tokens
3.5K
Snippets
9
Records
14
Agent score
36%

What's inside RepVGG

  1. Convert RepVGG from training-time to inference-time structure

    main

    RepVGG models use structural re-parameterization. To convert a training-time model (which has identity and 1x1 branches) into an efficient inference-time model (deploy mode), you can use one of two methods:

    1. Manual conversion: Iterate through the model modules and call switch_to_deploy() on every RepVGG block.
    2. Scripted conversion: Use the provided convert.py script.

    After conversion, you must build the model with the --deploy flag to use the inference-optimized structure.

    # Method 1: Manual conversion via switch_to_deploy
    for module in model.modules():
        if hasattr(module, 'switch_to_deploy'):
            module.switch_to_deploy()
    # Method 2: Using the conversion script
    python convert.py RepVGGplus-L2pse-train256-acc84.06.pth RepVGGplus-L2pse-deploy.pth -a RepVGGplus-L2pse
    
    # Then run inference with the --deploy flag
    python -m torch.distributed.launch --nproc_per_node 1 --master_port 12349 main.py --arch RepVGGplus-L2pse --data-path [/path/to/imagenet] --batch-size 32 --tag test --eval --resume RepVGGplus-L2pse-deploy.pth --deploy --opts DATA.DATASET imagenet DATA.IMG_SIZE [224 or 320]
  2. Train or finetune RepVGGplus models

    main

    When training or finetuning RepVGGplus, the model outputs a dictionary instead of a single tensor. The dictionary contains:

    • 'main': The output of the final layer.
    • '*aux*': The output of auxiliary classifiers.

    You must handle these auxiliary outputs by adding their weighted loss to the total loss. A common approach is to multiply the auxiliary loss by a factor of 0.1.

    # Build model and data loader as usual
    for samples, targets in enumerate(train_data_loader):
        # ......
        outputs = model(samples)                        # Your original code
        if type(outputs) is dict:                       
            # A training-time RepVGGplus outputs a dict. The items are:
                # 'main':     the output of the final layer
                # '*aux*':    the output of auxiliary classifiers
            loss = 0
            for name, pred in outputs.items():
                if 'aux' in name:
                    loss += 0.1 * criterion(pred, targets)          # Assume "criterion" is cross-entropy for classification
                else:
                    loss += criterion(pred, targets)
        else:
            loss = criterion(outputs, targets)          # Your original code
        # Backward as usual
        # ......
  3. Reproduce RepVGGplus-L2pse training

    main

    To train the RepVGGplus-L2pse model from scratch, you must activate mixup and use the raug15 preset for RandAug. This configuration is optimized for the 84.06% ImageNet accuracy result.

    python -m torch.distributed.launch --nproc_per_node 8 --master_port 12349 main.py --arch RepVGGplus-L2pse --data-path [/path/to/imagenet] --batch-size 32 --tag train_from_scratch --output-dir /path/to/save/the/log/and/checkpoints --opts TRAIN.EPOCHS 300 TRAIN.BASE_LR 0.1 TRAIN.WEIGHT_DECAY 4e-5 TRAIN.WARMUP_EPOCHS 5 MODEL.LABEL_SMOOTHING 0.1 AUG.PRESET raug15 AUG.MIXUP 0.2 DATA.DATASET imagenet DATA.IMG_SIZE 256 DATA.TEST_SIZE 320
  4. Use RepOptimizer for INT8 Quantization

    main
    For applications where INT8 quantization is essential, it is highly recommended to use RepOptimizer. Unlike standard quantization methods, RepOptimizer directly trains a VGG-like model via Gradient Re-parameterization without structural conversions, making quantization as straightforward as a regular model. This approach is used in YOLOv6.
  5. Test pretrained RepVGG models

    main

    To test the accuracy of downloaded pretrained models, use the main.py script with the --eval and --resume flags.

    Valid model names: RepVGGplus-L2pse, RepVGG-A0, RepVGG-A1, RepVGG-A2, RepVGG-B0, RepVGG-B1, RepVGG-B1g2, RepVGG-B1g4, RepVGG-B2, RepVGG-B2g2, RepVGG-B2g4, RepVGG-B3, RepVGG-B3g2, RepVGG-B3g4.

    python -m torch.distributed.launch --nproc_per_node 1 --master_port 12349 main.py --arch [model name] --data-path [/path/to/imagenet] --batch-size 32 --tag test --eval --resume [/path/to/weights/file] --opts DATA.DATASET imagenet DATA.IMG_SIZE [224 or 320]
  6. Reproduce original RepVGG training

    main

    To reproduce the original RepVGG results from the CVPR-2021 paper, train without mixup and use the weak RandAug preset.

    python -m torch.distributed.launch --nproc_per_node 8 --master_port 12349 main.py --arch [model name] --data-path [/path/to/imagenet] --batch-size 32 --tag train_from_scratch --output-dir /path/to/save/the/log/and/checkpoints --opts TRAIN.EPOCHS 300 TRAIN.BASE_LR 0.1 TRAIN.WEIGHT_DECAY 1e-4 TRAIN.WARMUP_EPOCHS 5 MODEL.LABEL_SMOOTHING 0.1 AUG.PRESET weak AUG.MIXUP 0.0 DATA.DATASET imagenet DATA.IMG_SIZE 224
  7. Fine-tune RepVGG for downstream tasks

    main

    To use RepVGG for other tasks (e.g., semantic segmentation with PSPNet), follow this workflow:

    1. Build your task-specific model (e.g., PSPNet) using the training-time RepVGG model as the backbone.
    2. Load the pre-trained weights into the backbone.
    3. Fine-tune the entire architecture on your target dataset.
    4. Convert the backbone to its inference-time structure using the conversion code provided in this repository before deployment.

    Do not convert the model before fine-tuning unless you insert BN layers after each conv (which may result in slightly lower performance).

  8. Quantize RepVGG using torch.quantization (QAT)

    main

    If direct INT8 quantization causes accuracy drops, you can use Quantization-Aware Training (QAT) with torch.quantization.

    1. Convert and Insert BN: Convert the model to its inference-time structure and insert Batch Normalization (BN) layers after the 3x3 convolutions. You must run the model on a dataset (like ImageNet) to initialize BN statistics so the output matches the inference-time model.
    2. Perform QAT: Build the model, prepare it using torch.quantization.prepare_qat, and conduct training.

    Note: The provided commands are examples and hyperparameters may require tuning.

    # 1. Convert to base model and insert BN
    python quantization/convert.py RepVGG-A0.pth RepVGG-A0_base.pth -a RepVGG-A0 
    python quantization/insert_bn.py [imagenet-folder] RepVGG-A0_base.pth RepVGG-A0_withBN.pth -a RepVGG-A0 -b 32 -n 40000
    
    # 2. Conduct QAT
    python quantization/quant_qat_train.py [imagenet-folder] -j 32 --epochs 20 -b 256 --lr 1e-3 --weight-decay 4e-5 --base-weights RepVGG-A0_withBN.pth --tag quanttest
  9. Modify configuration using --opts

    main
    You can override any configuration parameter defined in the project's config system by using the --opts flag followed by space-separated KEY VALUE pairs. This allows for quick experimentation without modifying source files.
  10. Resolve parameter name mismatches in DistributedDataParallel

    main

    When using DistributedDataParallel, PyTorch may prefix parameter names with module., causing load_state_dict to fail if the checkpoint does not have this prefix (or vice versa).

    Case 1: Checkpoint lacks module. but model has it Add the prefix to the checkpoint dictionary before loading:

    checkpoint = torch.load(...) 
    ckpt = {('module.' + k) : v for k, v in checkpoint.items()}
    model.load_state_dict(ckpt)

    Case 2: Checkpoint has module. but model does not Strip the prefix from the checkpoint dictionary:

    ckpt = {k.replace('module.', ''):v for k,v in checkpoint.items()}
    model.load_state_dict(ckpt)
    # Strip 'module.' prefix
    ckpt = {k.replace('module.', ''):v for k,v in checkpoint.items()}
    model.load_state_dict(ckpt)
  11. Use RepVGG for training and deployment via API

    main

    You can manage the transition between training and deployment modes using create_RepVGG_A0 (or other model creators) and repvgg_model_convert.

    from repvgg import repvgg_model_convert, create_RepVGG_A0
    
    # Training mode
    train_model = create_RepVGG_A0(deploy=False)
    train_model.load_state_dict(torch.load('RepVGG-A0-train.pth'))
    
    # Convert to deployment mode
    deploy_model = repvgg_model_convert(train_model, save_path='RepVGG-A0-deploy.pth')
    
    # OR: Create deployment model directly
    deploy_model = create_RepVGG_A0(deploy=True)
    deploy_model.load_state_dict(torch.load('RepVGG-A0-deploy.pth'))