Use spot instances to save costs on large model fine-tuning

Updated at:
Copy as MD

To reduce model fine-tuning costs, you can use a scaling group to automatically provision spot instances. This solution ensures training continuity by automatically creating a new instance and resuming from the latest checkpoint when a spot instance is subject to interruption and reclamation.

Solution overview

This solution uses a scaling group to enable low-cost, large model fine-tuning. It employs a spot-instance-first strategy and uses Object Storage Service (OSS) to persist checkpoints. During the training process:

  1. Prioritize spot instances: The scaling group prioritizes spot instances for training tasks and uses OSS to store checkpoint files.

  2. When a spot instance is interrupted and reclaimed: The scaling group first attempts to provision a spot instance from available inventory in other availability zones. If spot inventory is insufficient, it automatically provisions a pay-as-you-go instance and resumes training from the latest checkpoint.

  3. After spot inventory is restored: The scaling group automatically replaces the pay-as-you-go instance with a spot instance and resumes training from the latest checkpoint.

image

Note

If you are cost-sensitive and can tolerate longer training times, you can configure the scaling group to use only spot instances. In this configuration, training is paused when spot instances are unavailable and resumes automatically when inventory is restored, maximizing your cost savings. Learn more about combining scaling groups and spot instances.

Cost comparison

Important

The following cost comparison is for reference only. Actual savings may vary based on runtime conditions.

Assume a total training time of 12 hours, a spot instance price of 3.5/hour, and a pay-as-you-go instance price of 10/hour. The cost comparison is as follows.

Mode

Spot instances only

Hybrid (spot and pay-as-you-go)

Pay-as-you-go only

Description

When a spot instance is interrupted and reclaimed, training pauses. A new spot instance is automatically launched to continue training after capacity is restored.

Assume that of the 12 total training hours, 8 hours are on spot instances and 4 hours are on pay-as-you-go instances due to interruptions.

All training is performed on pay-as-you-go instances.

Cost

12h * 3.5/h = 42

8h * 3.5/h + 4h * 10/h = 68

12h * 10/h = 120

Savings vs. pay-as-you-go only

65%

43.33%

0%

Procedure

  1. Build a custom image with the base training environment.

    This image serves as the launch image for instances in the scaling group. It includes a startup script that automatically resumes training, ensuring that new instances can quickly start the task and run without manual intervention.

  2. Create and configure a scaling group.

    The scaling group automatically creates new spot or pay-as-you-go instances after an interruption, ensuring the training task continues.

  3. Start the training task.

    Enabling the scaling group triggers a scale-out event, creating an instance that automatically begins the training task.

  4. Simulate an interruption (verification).

    Manually release an instance to simulate an interruption or reclamation scenario. Verify that a new instance is launched and that the training task resumes automatically to ensure stability and reliability.

1. Build a custom training image

This topic demonstrates how to perform self-cognition fine-tuning on the DeepSeek-R1-Distill-Qwen-7B model by using the Swift training framework on a single-machine, single-GPU setup.

First, create an instance with the required training environment and dependencies. Then, create a custom image from this instance to serve as the launch image for your scaling group, which improves startup efficiency. The image includes an automatic training script and a boot-start service to automate the workflow. The architecture of the ECS instance used to create this image is shown in the following figure.

image

Key components include:

  • Base training environment dependencies: Includes the GPU driver, CUDA, and relevant Python dependencies, which vary based on the training framework.

  • Automatic training script: This script must automatically check whether to resume from the latest checkpoint and if training is complete.

  • Automatic bucket mount on startup: When the training script starts, it reads model weights, datasets, and generated checkpoint files from the OSS bucket.

  • Boot-start service: This service ensures that the training script runs automatically after the instance starts, reading the necessary files from the bucket to begin or continue training.

After you understand these components, follow the steps below to build the image.

1.1 Create an instance and build the environment

This instance serves as a template from which to create a custom image. Later, the scaling group will use this image to automatically create new instances.

  1. Go to the ECS console to create a GPU instance.

    First, create a pay-as-you-go GPU instance to set up the base environment. This tutorial uses an ecs.gn7i-c8g1.2xlarge instance in Availability Zone J of the China (Hangzhou) region. Configure the instance as follows:

    1. Billing Method: Pay-As-You-Go.

    ②:Region. China (Hangzhou).

    ③④: Network and Zone. Select a VPC and a vSwitch. If they do not exist, you can create them by following the on-screen instructions.

    ⑤⑥: Select instance type. Select ecs.gn7i-c8g1.2xlarge.

    ⑦⑧⑨: Images: Ubuntu 22.04 64-bit.

    ⑩: Auto-install GPU driver. Select the versions: CUDA version 12.4.1, Driver version 550.127.08, and CUDNN version 9.2.0.82.

    ⑪: System Disk > Capacity. 60 GiB.

    ⑫⑬⑭: Assign public IPv4 address to allow the instance to access the internet and download model files. For Bandwidth Billing Method, select Pay-by-traffic. For Maximum Bandwidth, select 100 Mbps.

    ⑮⑯⑰: Create a new basic security group. Open at least the SSH (TCP: 22) and ICMP (IPv4) ports to allow remote connections.

    ⑱⑲⑳: Logon Credential. This credential is used to log on to the instance. You can select a key pair or a password. Follow the on-screen prompts to complete the configuration.

    21:Instance Name. Specify a name for the instance to make it easy to remember and find. This topic uses ess-lora-deepseek7b-template as an example.

    After completing the configuration, click Confirm Order and wait for the instance to be created.

  2. After the instance is created, connect to it and wait for the GPU driver to install.

    1. Go to ECS console - Instances.

    2. Find the instance you created in the previous step, and click Connect in the Actions column. Connect to the instance using Workbench and log in as prompted.

      If you cannot find the instance, your current region may not match the instance's region. You can switch regions in the upper-left corner.
      If the instance is stopped, refresh the page and wait for it to start.
    3. After connecting to the instance, wait for the GPU driver to finish installing. After installation, you are prompted to reconnect.

      If the interface freezes, try refreshing the page and reconnecting to the instance.
      Welcome to Alibaba Cloud Elastic Compute Service !
      
      Last login: Tue Mar 18 21:12:39 2025 from xxx
        % Total    % Received % Xferd  Average Speed   Time    Time     Current
                                       Dload  Upload   Total   Spent    Left  Speed
      100    21  100    21    0     0    875      0 --:--:-- --:--:-- --:--:--   913
      
      Driver-xxx installing, it takes 0 minutes. Remaining installation time 11 to 15 minutes!
      [cuda-12.4.1. Installing, it tasks 2 to 5 minutes. Remaining installation time 9 to 12 minutes!

      I can't see this page. How do I verify the installation?

      If this interface does not appear after you connect to the instance, the driver may already be installed. You can run the following command to confirm the driver installation:

      nvidia-smi

      If the following output appears, the installation is complete.

      root@ixxx:~# nvidia-smi
      Wed Mar 26 09:40:48 2025
      +-----------------------------------------------------------------------------------------+
      | NVIDIA-SMI 550.127.08    Driver Version: 550.127.08    CUDA Version: 12.4              |
      |-------------------------------------------+------------------------+-------------------|
      | GPU  Name        Persistence-M |  Bus-Id        Dis.A | Volatile Uncorr. ECC |
      | Fan  Temp  Perf    Pwr:Usage/Cap |                     | Memory-Usage | GPU-Util  Compute M. |
      |===========================================================================================|
      |  0   NVIDIA A10         On |  00000000:00:07.0 Off |                    0 |
      |  0%   27C    P8       9W / 150W |      1MiB / 23028MiB |      0%      Default |
      +-------------------------------------------+------------------------+-------------------+
      
      +-----------------------------------------------------------------------------------------+
      | Processes:                                                                               |
      |  GPU   GI   CI     PID   Type   Process name                         GPU Memory         |
      |        ID   ID                                                        Usage              |
      |=========================================================================================|
      |  No running processes found                                                              |
      +-----------------------------------------------------------------------------------------+

      If this output does not appear, the driver is not installed or has an issue. We recommend that you create a new instance and select Auto-install GPU driver during setup.

      To manually install the driver, see Manually install the Tesla driver on a GPU-accelerated compute-optimized Linux instance.
  3. Install Python dependencies.

    Run the following commands to install the required dependencies for training.

    The Ubuntu 22.04 64-bit image used in this tutorial already includes Python 3.10, so no separate Python installation is needed.
    # The Ubuntu 22.04 image includes Python 3.10, so no extra installation is needed.
    python3 -m pip install --upgrade pip
    # Switch to the Alibaba Cloud internal PyPI mirror.
    pip config set global.index-url http://mirrors.cloud.aliyuncs.com/pypi/simple/
    
    pip install modelscope==1.22.3
    pip install openai==1.61.0
    pip install tqdm==4.67.1
    pip install "vllm>=0.5.1" -U
    pip install "lmdeploy>=0.5,<0.6.5" -U --no-deps
    pip install autoawq -U --no-deps
    pip install auto_gptq optimum bitsandbytes -U
    pip install ms-swift[all]
    pip install timm -U
    pip install deepspeed==0.14.* -U
    pip install qwen_vl_utils decord librosa pyav icecream -U
While waiting for dependencies to install, you can click the image icon in the upper-right corner to open a multi-terminal and proceed with Step 1.2 simultaneously.

1.2 Create and mount an OSS bucket

In this step, create a bucket in OSS and mount it as a data disk to the ECS instance. This bucket will store the model weight files, datasets, and checkpoints generated during training.

  1. Go to the OSS console to create a bucket.

    The following are key configuration parameters. Keep the default values for any unmentioned parameters.

    2. Bucket. You will use this bucket name when you mount the bucket later.

    3. Region. Select Region-specific. The region must be the same as the region of the ECS instance. In this example, the region is China (Hangzhou).

    ECS instances can access OSS buckets in the same region over the internal network at no charge for traffic. For more information, see Access OSS resources from an ECS instance over an internal network.
  2. Create and attach a RAM role.

    A RAM role authorizes the ECS instance to access your OSS bucket. To create and attach a RAM role, follow these steps:

    1. In the RAM console, create a RAM role. Key configuration parameters are described below.

      Navigate to the Roles page of the Resource Access Management (RAM) console and click Create Role.

      ②: Principal type. Select Cloud Service.

      ③: Principal name. Select ECS. This specifies that the role will be granted to an ECS instance.

      ④: Click OK and set a name for the RAM role as prompted.

    2. In the RAM console, create the following custom policy.

      Go to the Policies page of the Resource Access Management (RAM) console and click Create Policy.

      Select the Script Editor tab and enter the following policy script.

      ③: This policy grants full access to a specific bucket. The policy script is as follows.

      Important

      When you set the policy, replace <bucket_name> with your Bucket.

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "oss:*",
                  "Resource": [
                      "acs:oss:*:*:<bucket_name>",
                      "acs:oss:*:*:<bucket_name>/*"
                  ]
              }
          ]
      }

      After the configuration, click OK and set a name for the policy as prompted.

    3. In the RAM console, grant permissions to the RAM role.

      ⑥: Principal. Select the RAM role that you created earlier.

      ⑦: Permission Policy. Select the custom policy that you created earlier.

      After the configuration, click OK.

    4. Go to the ECS console and attach the RAM role to the instance.

      If you cannot find the instance, your current region may not match the instance's region. You can switch regions in the upper-left corner.

      In the instance list on the ECS console, find the target instance and attach the RAM role that you created in Step 1.2 from the Actions column.

  3. Mount the bucket to the ECS instance.

    1. Connect to the instance created in Step 1.1 and run the following command to install the ossfs tool.

      wget https://gosspublic.alicdn.com/ossfs/ossfs_1.91.5_ubuntu22.04_amd64.deb
      apt-get update
      DEBIAN_FRONTEND=noninteractive apt-get install gdebi-core
      DEBIAN_FRONTEND=noninteractive gdebi -n ossfs_1.91.5_ubuntu22.04_amd64.deb
    2. Run the following command to complete the mount operation. Make sure to replace the following placeholders in the command:

      • <bucket_name>: Replace with the Bucket of the bucket you created.

        View bucket name

        Go to the OSS console to find the bucket you created.

      • <ecs_ram_role>: Replace with the name of the RAM role you created.

        View RAM role name

        Go to the ECS console, find the instance with the attached RAM role, and go to the Attach/Detach RAM Role page

        . On this page, you can view the RAM roles attached to the instance.

        If you cannot find the instance, your current region may not match the instance's region. You can switch regions in the upper-left corner.

        In the instance list of the ECS console, find the ess-lora-deepseek-7b-template instance and attach the RAM role created in Step 1.2 from the Actions column.

      • <internal_endpoint>: Replace with oss-cn-hangzhou-internal.aliyuncs.com.

        Important

        This tutorial uses a bucket in the China (Hangzhou) region, so the VPC internal endpoint is oss-cn-hangzhou-internal.aliyuncs.com.

        How to get the endpoint if your bucket is not in the Hangzhou region

        If your OSS bucket is not in the Hangzhou region, get the VPC internal endpoint and replace the value of <internal_endpoint>.

        On the Overview page of your bucket in the OSS console, find the Access Endpoint information. Get the endpoint address for VPC Network Access (Internal Network) from ECS (for example, oss-cn-hangzhou-internal.aliyuncs.com).

      # Replace with your bucket name, internal endpoint, and RAM role.
      BUCKET_NAME="<bucket_name>"
      ECS_RAM_ROLE="<ecs_ram_role>"
      INTERNAL_ENDPOINT="<internal_endpoint>"
      
      # Bucket mount path
      BUCKET_MOUNT_PATH="/mnt/oss-data"
      
      # 1. Back up the fstab file before mounting.
      cp /etc/fstab /etc/fstab.bak
      
      # 2. Create the mount directory.
      mkdir $BUCKET_MOUNT_PATH
      # 3. Mount the bucket to the instance.
      ossfs $BUCKET_NAME $BUCKET_MOUNT_PATH -ourl=$INTERNAL_ENDPOINT -oram_role=http://100.100.100.200/latest/meta-data/ram/security-credentials/$ECS_RAM_ROLE
      # 4. Set auto-mount on startup.
      echo "ossfs#$BUCKET_NAME $BUCKET_MOUNT_PATH fuse _netdev,url=http://$INTERNAL_ENDPOINT,ram_role=http://100.100.100.200/latest/meta-data/ram/security-credentials/$ECS_RAM_ROLE,allow_other 0 0" | sudo tee -a /etc/fstab
  4. (Verification) Test if the storage space is available.

    1. Upload any file to the OSS bucket.

      In the OSS console, go to the Files page of your bucket. Click Upload File and upload a test file to verify the mount.

    2. In the instance, run the following command to check if you can see the file from the OSS bucket in the directory.

      ls /mnt/oss-data/

      If the file is visible, the mount was successful.

      root@ixxx:~# ls /mnt/oss-data/
      test.txt

    Why can't I see the file in the OSS bucket?

    This may be due to a mount failure. Follow these steps to troubleshoot:

    1. Check if the ECS instance and the OSS bucket are in the same region. Ensure that <internal_endpoint> in the mount command has been correctly replaced with the bucket's VPC internal endpoint.

    2. Check if <bucket_name> in the mount command has been correctly replaced with the name of your OSS bucket.

    3. Try reattaching the RAM role to the ECS instance. Also, check if <ecs_ram_role> in the mount command matches the name of the attached RAM role.

    4. Correctly replace <bucket_name>, <internal_endpoint>, and <ecs_ram_role> in the following command, and then execute it to remount.

      # Replace with your bucket name, internal endpoint, and RAM role.
      BUCKET_NAME="<bucket_name>"
      ECS_RAM_ROLE="<ecs_ram_role>"
      INTERNAL_ENDPOINT="<internal_endpoint>"
      
      # Bucket mount path
      BUCKET_MOUNT_PATH="/mnt/oss-data"
      
      # 1. Try to unmount.
      umount $BUCKET_MOUNT_PATH
      
      # 2. Restore /etc/fstab from backup.
      cp /etc/fstab.bak /etc/fstab
      
      # 3. Remount the bucket to the instance.
      ossfs $BUCKET_NAME $BUCKET_MOUNT_PATH -ourl=$INTERNAL_ENDPOINT -oram_role=http://100.100.100.200/latest/meta-data/ram/security-credentials/$ECS_RAM_ROLE
      # 4. Re-enable auto-mount on startup.
      echo "ossfs#$BUCKET_NAME $BUCKET_MOUNT_PATH fuse _netdev,url=http://$INTERNAL_ENDPOINT,ram_role=http://100.100.100.200/latest/meta-data/ram/security-credentials/$ECS_RAM_ROLE,allow_other 0 0" | sudo tee -a /etc/fstab
    1. Check if you can see files from the OSS bucket in the mount directory (/mnt/oss-data).

      ls /mnt/oss-data/

1.3 Prepare the model and dataset

The model weights and dataset used in this tutorial are downloaded from the ModelScope community. After you connect to the instance, follow the steps below. Download the model and dataset to the directory where the OSS bucket is mounted and wait for the download to complete.

  1. Download the dataset

    # Bucket mount path
    BUCKET_MOUNT_PATH="/mnt/oss-data"
    
    # Download the fine-tuning dataset from the ModelScope community
    # Use the modelscope tool installed in Step 1.1
    modelscope download --dataset swift/self-cognition --local_dir $BUCKET_MOUNT_PATH/self-cognition
    modelscope download --dataset AI-ModelScope/alpaca-gpt4-data-zh --local_dir $BUCKET_MOUNT_PATH/alpaca-gpt4-data-zh
    modelscope download --dataset AI-ModelScope/alpaca-gpt4-data-en --local_dir $BUCKET_MOUNT_PATH/alpaca-gpt4-data-en
    If the download progress stalls, press Enter several times.
  2. Download the model weights

    Important

    The model weight file is large. If the download fails or you see a please try again message, retry the command to resume the download.

    # Bucket mount path
    BUCKET_MOUNT_PATH="/mnt/oss-data"
    
    # Download the DeepSeek-R1-Distill-Qwen-7B model from the ModelScope community
    modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --local_dir $BUCKET_MOUNT_PATH/DeepSeek-R1-Distill-Qwen-7B
    If the download progress stalls, press Enter several times.
  3. Test the model weights

    After the download is complete, you can run the following command to perform an inference test with the model and verify that the model weight file is complete.

    # Bucket mount path
    BUCKET_MOUNT_PATH="/mnt/oss-data"
    
    CUDA_VISIBLE_DEVICES=0 swift infer \
        --model $BUCKET_MOUNT_PATH/DeepSeek-R1-Distill-Qwen-7B \
        --stream true \
        --infer_backend pt \
        --max_new_tokens 2048

    After the model loads, you can start a conversation with the large language model. If the model weights fail to load, download them again.

    [INFO:swift] Start time of running main: 2025-03-26 13:35:50.564493
    [INFO:swift] request_config: RequestConfig(max_tokens=2048, temperature=None, top_k=None, top_p=None, repetition_penalty=None, num_beams=1, stop=[], seed=None, stream=True, logprobs=False, top_logprobs=None, n=1, best_of=None, presence_penalty=0.0, frequency_penalty=0.0, length_penalty=1.0)
    [INFO:swift] Input 'exit' or 'quit' to exit the conversation.
    [INFO:swift] Input 'multi-line' to switch to multi-line input mode.
    [INFO:swift] Input 'reset-system' to reset the system and clear the history.
    [INFO:swift] Input 'clear' to clear the history.
    <<< Who are you?

    After the test is complete, you can enter exit to end the conversation.

1.4 Write an automatic training script

  1. Write an automatic training script.

    Run the following command to create an automatic training script and grant it executable permissions. This script automatically resumes training from the latest checkpoint and determines when training is complete.

    # Create an automatic training script.
    cat <<EOF > /root/train.sh
    #!/bin/bash
    
    # Bucket mount path
    BUCKET_MOUNT_PATH="/mnt/oss-data"
    
    # Storage directory for model weights and datasets
    MODEL_PATH="\$BUCKET_MOUNT_PATH/DeepSeek-R1-Distill-Qwen-7B"
    DATASET_PATH="\$BUCKET_MOUNT_PATH/alpaca-gpt4-data-zh#500 \$BUCKET_MOUNT_PATH/alpaca-gpt4-data-en#500 \$BUCKET_MOUNT_PATH/self-cognition#500"
    
    # Set the output directory
    OUTPUT_DIR="\$BUCKET_MOUNT_PATH/output"
    mkdir -p "\$OUTPUT_DIR"
    
    # Logic to check if training is already complete
    if [ -f "\$OUTPUT_DIR/logging.jsonl" ]; then
        last_line=\$(tail -n 1 "\$OUTPUT_DIR/logging.jsonl")
        if echo "\$last_line" | grep -q "last_model_checkpoint" && echo "\$last_line" | grep -q "best_model_checkpoint"; then
            echo "Training already completed. Exiting."
            exit 0
        fi
    fi
    
    # Initialize resume argument
    RESUME_ARG=""
    
    # Find the latest checkpoint
    LATEST_CHECKPOINT=\$(ls -dt \$OUTPUT_DIR/checkpoint-* 2>/dev/null | head -1)
    
    if [ -n "\$LATEST_CHECKPOINT" ]; then
        RESUME_ARG="--resume_from_checkpoint \$LATEST_CHECKPOINT"
        echo "Resume training from: \$LATEST_CHECKPOINT"
    else
        echo "No checkpoint found. Starting new training."
    fi
    
    # Start the training command
    CUDA_VISIBLE_DEVICES=0 swift sft \\
        --model \$MODEL_PATH \\
        --train_type lora \\
        --dataset \$DATASET_PATH \\
        --torch_dtype bfloat16 \\
        --num_train_epochs 1 \\
        --per_device_train_batch_size 1 \\
        --per_device_eval_batch_size 1 \\
        --learning_rate 1e-4 \\
        --lora_rank 8 \\
        --lora_alpha 32 \\
        --target_modules all-linear \\
        --gradient_accumulation_steps 16 \\
        --eval_steps 50 \\
        --save_steps 10 \\
        --save_total_limit 5 \\
        --logging_steps 5 \\
        --max_length 2048 \\
        --output_dir "\$OUTPUT_DIR" \\
        --add_version False \\
        --overwrite_output_dir True \\
        --system 'You are a helpful assistant.' \\
        --warmup_ratio 0.05 \\
        --dataloader_num_workers 4 \\
        --model_author swift \\
        --model_name swift-robot \\
        \$RESUME_ARG
    EOF
    
    # Grant executable permissions
    chmod +x /root/train.sh

    Test if the script runs correctly

    Run the following command to test if the script runs correctly:

    ./train.sh

    If the model loads and training starts normally after you run the command, it confirms that the model file is correct and all dependencies are present. Press CTRL + C to exit the training.

    Train:   0%|          | 0/93 [00:00<?, ?it/s]

    If it does not run correctly, reinstall the Python dependencies from Step 1.1 and re-download the weights and dataset from Step 1.3.

  2. Create a Linux service and set it to start on boot.

    Run the following command to create a service and configure the training script to start automatically on boot.

    # Create log storage directory
    mkdir -p /root/train-service-log
    
    # Write the Service configuration file
    cat <<EOF > /etc/systemd/system/train.service
    [Unit]
    Description=Train AI Model Script
    After=network.target local-fs.target remote-fs.target
    Requires=local-fs.target remote-fs.target
    
    [Service]
    ExecStart=/root/train.sh
    WorkingDirectory=/root/
    User=root
    Environment="PATH=/usr/bin:/usr/local/bin"
    Environment="CUDA_VISIBLE_DEVICES=0"
    StandardOutput=append:/root/train-service-log/train.log
    StandardError=append:/root/train-service-log/train_error.log
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    # Reload systemd configuration
    systemctl daemon-reload
    # Configure the train.service to start on boot
    systemctl enable train.service

    The command returns the following output upon completion:

    Created symlink /etc/systemd/system/multi-user.target.wants/train.service → /etc/systemd/system/train.service.

1.5 Build the custom image

After completing all previous steps, create a custom image from the configured instance. This image serves as the launch image for new instances during scale-out, which eliminates the need to reinstall dependencies.

  1. Go to the Instances page of the ECS console.

  2. Create the image as described below.

    In the instance list on the ECS console, find the target instance. In the Actions column, click More > Disks and Images > Create Custom Image. Complete the image creation as prompted.

  3. Wait for the image to be created. This process takes about 5 minutes. You can check the creation progress on the Images page of the ECS console.

Note

After the image is created, you can release the instance created in Step 1.1.

2. Create a scaling group

Configure a scaling group to automate instance management. The scaling group ensures that after an instance is interrupted, a new spot or pay-as-you-go instance is automatically created to continue the training task. When spot instances become available, they will automatically replace pay-as-you-go instances to save costs.

2.1 Create a scaling group

First, you need to create a scaling group. Follow these steps.

  1. Go to the Auto Scaling console to create a scaling group.

    Important

    Make sure the scaling group is in the same region as the instance created in Step 1.1.

  1. Configure the scaling group as follows. For detailed parameter descriptions, see Parameters.

    Configure the following parameters: Set Scaling Group Name to ess-lora-deepseek-7b, Type to ECS, and Source for Instance Configuration to Existing instance. Set Min. Instances to 0, Max. Instances to 1, and keep the Default Cooldown Time at 300 seconds.

    Important

    When you select a VPC and vSwitch at ⑤⑥, we recommend that you select vSwitches in multiple availability zones. This allows the scaling group to provision resources across zones, increasing the probability of successfully creating spot instances.

    Important

    If you want to maximize cost savings by using only spot instances for training, you must disable both Use Pay-as-you-go Instances to Supplement Spot Capacity and Replace Pay-as-you-go Instances with Spot Instances.

  1. After the configuration, click Create. You can then proceed to create a scaling configuration as prompted.

2.2 Create a scaling configuration

A scaling configuration defines the specifications, image, and other information for instances in a scaling group. After you configure it, the scaling group automatically creates new instances based on these settings. On the Create Scaling Configuration page, complete the following configurations:

Not on the Create Scaling Configuration page?

You can return to the Create Scaling Configuration page by following these steps.

  1. Go to the Auto Scaling console.

    Important

    Make sure the scaling group is in the same region as the instance created in Step 1.1.

  2. In the scaling group list, find the scaling group created in Step 2.1 and click its ID to go to the details page. Follow the steps below to navigate to the Create Scaling Configuration page.

    On the scaling group details page, switch to the Scaling Configurations tab and click Create Scaling Configuration.

1. Scaling Configuration Name: ess-config.

②: Billing Method: Spot Instance.

③ and ④: Image. Select Custom Images, and then select the custom image that you created in Step 1.5.

⑤: Instance Configuration Mode. Select Specify Instance Type.

6. Instance Usage Duration. Select 1 Hour. After the instance runs for one hour, the system starts to check whether to interrupt and reclaim the instance.

If you select No Specified Usage Duration, you can use spot instances at a lower cost, but they have a higher probability of interruption. This may lead to the instance being reclaimed before a valid checkpoint can be created, which slows down training progress. For more information about the differences between these two options, see Use spot instances in scaling groups to reduce costs.

⑦: Highest price per instance. Select Use Automatic Bid to automatically bid based on the market price.

8. Select an instance type. Select the instance type that you set when you created the instance in Step 1.1, which is ecs.gn7i-c8g1.2xlarge.

9. Security Group. Select the security group that you configured when you created the instance in Step 1.1.

This tutorial is an offline training solution, so no public IP address needs to be assigned.

⑩: Logon Credential. Select Use Predefined Password.

⑪⑫⑬: Advanced Settings > Instance RAM Role. Select the RAM role created in Step 1.2. When the scaling group automatically creates instances, this RAM role will be automatically attached to the new instances.

Note

After you click Create, you may see a prompt about insufficient scaling configuration strength. Click Continue.

After you create the scaling configuration, enable the scaling configuration and enable the scaling group as prompted.

After the scaling configuration is created successfully, click Enable Configuration in the dialog box that appears.

In the Select Scaling Configuration confirmation dialog box, click OK.

In the Enable Scaling Group confirmation dialog box, click OK to enable the scaling group.

3. Start the training task

After the scaling group is configured, adjust the expected number of instances to 1. The steps are as follows.

Go to the scaling group details page and view the Instance Scaling Overview. The current instance counts are all 0.

Click Modify in the Instance Scaling Overview section. Enable the Expected Number of Instances switch, set the value to 1, and click OK. The scaling group will automatically create a spot instance.

The scaling group then automatically creates a new instance and starts the training task.

The scaling group periodically checks if the number of instances in the group matches the expected number of instances. Because the current count is 0, a scale-out is automatically triggered to create a new instance.
Note
  • After you adjust the expected number of instances, there may be a delay in instance creation. You can view ongoing activities on the Scaling Activities tab.

  • After the instance is created and started, you can find an output folder in your OSS bucket. This folder stores the checkpoint files generated during training.

4. Simulate an interruption (verification)

After the instance starts the training task, check the output directory in your OSS bucket to see if a folder such as checkpoint-10 has been created. Once a checkpoint is generated, you can manually release the training instance to simulate an interruption. The steps to manually release an instance are as follows:

  1. Manually release the instance.

    1. First, go to the Instances tab of the scaling group and click the Instance ID to go to the corresponding Instance Details page.

    2. On the instance details page, click All Operations > Release in the upper-right corner and follow the prompts to release the instance.

  2. Check if training resumes from the latest checkpoint.

    Wait for the scaling group to create a new instance. After the instance is created, connect to it and view the task log.

    1. Go to the Instances tab of the scaling group and click the Instance ID to go to the corresponding Instance Details page.

    2. Click Connect in the upper-right corner and connect to the instance as prompted.

    3. Run the following command to view the model training log. This log output path was set for the boot-start service in Step 1.4.

      cat /root/train-service-log/train.log

      As you can see, the training task resumes from the latest checkpoint.

      root@ixxx:~# cat train-service-log/train.log
      Resume training from: /mnt/oss-data/output/checkpoint-10
      run sh: /usr/bin/python3 /usr/local/lib/python3.10/dist-packages/xxx
        s-data/self-cognition#500 --torch_dtype bfloat16 --num_train_epochs xxx
        --eval_steps 50 --save_steps 10 --save_total_limit 5 --logging_steps xxx
        --num_workers 4 --model_author swift --model_name swift-robot --resume xxx

Next steps

Use the fine-tuned model for inference

After the fine-tuning task is complete, a checkpoint-93 folder is generated in the output directory of the OSS bucket. You can then connect to the instance and run the following command to interact with the fine-tuned model.

# Bucket mount path
BUCKET_MOUNT_PATH="/mnt/oss-data"

# Set the output directory
OUTPUT_DIR="$BUCKET_MOUNT_PATH/output"

# Find the latest checkpoint
LATEST_CHECKPOINT=$(ls -dt $OUTPUT_DIR/checkpoint-* 2>/dev/null | head -1)

CUDA_VISIBLE_DEVICES=0 \
swift infer \
    --adapters $LATEST_CHECKPOINT \
    --stream true \
    --temperature 0 \
    --max_new_tokens 2048
[INFO:swift] Start time of running main: 2025-03-26 15:15:11.595764
[INFO:swift] request_config: RequestConfig(max_tokens=2048, temperature=0.0, top_k=None, top_p=None, repetition_penalty=None, num_beams=1, stop=[], seed=None, stream=True, logprobs=False, top_logprobs=None, n=1, best_of=None, presence_penalty=0.0, frequency_penalty=0.0, length_penalty=1.0)
[INFO:swift] Input 'exit' or 'quit' to exit the conversation.
[INFO:swift] Input 'multi-line' to switch to multi-line input mode.
[INFO:swift] Input 'reset-system' to reset the system and clear the history.
[INFO:swift] Input 'clear' to clear the history.
<<< Who are you?

Release resources

To avoid incurring further charges, you can release the resources used in this tutorial by following these steps.

  1. Delete the scaling group. Deleting the scaling group created in Step 2 will also delete the instances it automatically created.

  2. Delete the custom image. Delete the custom image built in Step 1.5.

  3. Delete the bucket. Delete the OSS bucket created in Step 1.2.

  4. Delete the RAM role. Delete the RAM role created in Step 1.2.

  5. Release the instance. Release the instance created in Step 1.1.

Recommendations for production environments

Before using this solution in production, adapt it based on your business needs and the following recommendations.

  • Integrate CloudMonitor for interruption handling

    When applying this solution in a production environment, we recommend that you integrate CloudMonitor into your training code to detect and respond to spot instance interruption events. Saving a checkpoint five minutes before an interruption reduces progress loss when resuming training. The improved architecture is as follows:

    image

  • Establish a task recovery mechanism

    In this tutorial's example, training resumes automatically from the latest checkpoint without checking its validity. In a production application, it is recommended to implement an anomaly detection mechanism to rule out invalid checkpoints and automatically resume training from the latest valid one.

  • Improve the task completion process

    You can add logic to your training code to determine when the task is complete. Upon completion, use the CLI or SDK to call the scaling group's API and change the expected number of instances to 0. The scaling group then automatically releases any excess instances, avoiding unnecessary costs.

    Additionally, when the task is complete, you can report custom events to CloudMonitor. This allows you to receive notifications about the training results by email, SMS, or DingTalk chatbot.

  • Use a high-performance file system

    When you train models with a large number of parameters, OSS can become a system bottleneck. We recommend that you use a high-throughput, low-latency file system such as CPFS as a mounted file system to improve performance.

  • Configure multi-AZ vSwitches for higher availability

    If you configure a vSwitch in only a single availability zone, the scaling group can create instances only in that zone, which can easily lead to scale-out failures due to insufficient capacity. We recommend that you configure vSwitches in multiple availability zones. When a spot instance is reclaimed, the system automatically tries to create a new one in other zones, increasing the availability of spot instances.

References