Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

บทความนี้อธิบายความหมายและการทำงานเบื้องต้นของ NCCL (NVIDIA Collective Communications Library) เพื่อเพิ่มประสิทธิภาพการสื่อสารระหว่าง GPU พร้อมทั้งนำเสนอผลการทดลองของการตั้งค่า parameter เพื่อให้เข้าใจและเป็นแนวทางในการนำไปใช้งาน

...

Info

ตัวอย่างการตั้งค่า

หากกำหนด NCCL_SOCKET_NTHREADS เป็น 8 ; CPU จะใช้งาน 8 Threads[1]

และตั้งค่า NCCL_NSOCKS_PERTHREAD เป็น 2 ; แต่ละ Thread จะใช้ Network Socket 2 ตัว ในการสื่อสาร

ดังนั้นจะใช้ทั้งสิ้น 16 Network Socket

[1] สำหรับเครื่อง LANTA ที่ปิด Hyper-threading ไว้ การระบุจำนวน thread จะเทียบเท่ากับการใช้งาน CPU core
Panel
panelIconIdatlassian-warning
panelIcon:warning:
bgColor#FFFAE6

โดยที่ผลคูณของ NCCL_SOCKET_NTHREADS และ NCCL_NSOCKS_PERTHREAD จะต้องไม่เกิน 64.

โดย parameter 2 ตัวนี้ จะใช้ทรัพยากรส่วนหนึ่งของ CPU ในการสื่อสารกันระหว่าง GPU/node ซึ่งในการประมวลผล main task จะต้องใช้ทรัพยากรของ CPU เช่นกันจึงต้อง balance เพื่อหาค่า parameter ที่เหมาะสม

...

Code Block
languagebash
#!/bin/bash
#SBATCH -p gpu                           # Specify partition [Compute/Memory/GPU]
#SBATCH -c 64                            # Specify number of processors per task
#SBATCH --ntasks-per-node=1		         # Specify number of tasks per node
#SBATCH --gpus-per-node=4		         # Specify total number of GPUs
#SBATCH -t 1:00:00                       # Specify maximum time limit (hour: minute: second)
#SBATCH -A xxyyyyyy                      # Specify project name
#SBATCH -J nccl-test                     # Specify job name
#SBATCH -o ./logs/finetune-%j.out        # Specify output file

module restore
module load Mamba
module load PrgEnv-gnu
module load cpe-cuda/23.03
module load cudatoolkit/23.3_11.8

: "${NTHREADS:=8}"
: "${PTHREADS:=2}"
: "${BATCH_SIZE:=4}"
: "${DEEPSPEED_STAGE:=3}"
: "${MODEL_SIZE:=7b}"
: "${TASK:=finetune}"
: "${RUN_WITH:=conda}"
: "${ENV_PATH:=}"
: "${SCALING_TYPE:=}"
: "${WO_LORA:=NO}"
: if [ "$PROJ_PATH" == "" ]; then
    echo "PROJ_PATH is not set, please export the path to the project directory"
    exit 1
fi
if [ "$SHARED_PATH" == "" ]; then
    echo "SHARED_PATH is not set, please export the path to the shared directory"
    exit 1
fi
if [ "$CACHE_PATH" == "" ]; then
    echo "CACHE_PATH is not set, please export the path to the cache directory"
    exit 1
fi
if [ "$ENV_PATH" == "" ]; then
    echo "ENV_PATH is not set, please export the path to the environment"
    exit 1
fi"${PROJ_PATH:=}"
: "${SHARED_PATH:=}"
: "${CACHE_PATH:=}"
: "${ENV_PATH:=}"

conda deactivate
conda activate $ENV_PATH

export WANDB_MODE="offline"
export HOSTNAMES=$(scontrol show hostnames "$SLURM_JOB_NODELIST")
export MASTER_ADDR=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | head -n 1)
export MASTER_PORT=12802
export COUNT_NODE=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | wc -l)

LOG_DIR="./logs/${NTHREADS}nth-${PTHREADS}pth-${SLURM_JOB_ID}"

mkdir -p $LOG_DIR/node_log

export LOG_DIR=$LOG_DIR

export NCCL_TIMEOUT=3600000
export NCCL_DEBUG=DEBUG
export NCCL_SOCKET_IFNAME=hsn
export NCCL_SOCKET_NTHREADS=$NTHREADS
export NCCL_NSOCKS_PERTHREAD=$PTHREADS
export NCCL_DEBUG_FILE=${LOG_DIR}/nccl-${SLURM_JOB_ID}.log
export NCCL_TOPO_DUMP_FILE=${LOG_DIR}/nccl-topo-${SLURM_JOB_ID}.log
export BATCH_SIZE=$BATCH_SIZE
export DEEPSPEED_STAGE=$DEEPSPEED_STAGE
export MODEL_SIZE=$MODEL_SIZE

export TORCH_NCCL_BLOCKING_WAIT=0
export TORCH_EXTENSIONS_DIR=$CACHE_PATH
export HF_HUB_CACHE="$CACHE_PATH/huggingface"
export HF_HOME="$CACHE_PATH/huggingface"
export HF_DATASETS_CACHE="$CACHE_PATH/huggingface"
export TORCH_HOME=$CACHE_PATH
export XDG_CACHE_HOME=$CACHE_PATH
export HF_DATASETS_OFFLINE=1 
export HF_HUB_OFFLINE=1

echo -------ENVIRONMENT-------
echo Python Path: $(which python)
echo Batch Size: $BATCH_SIZE
echo Deepspeed Stage: $DEEPSPEED_STAGE
echo Model Size: $MODEL_SIZE
echo Train with LoRA: $WO_LORA
echo -------------------------
echo NTHREADS: $NTHREADS
echo PTHREADS: $PTHREADS
echo NODES: $COUNT_NODE
echo HOSTNAMES: $HOSTNAMES
echo MASTER_ADDR: $MASTER_ADDR
echo MASTER_PORT: $MASTER_PORT
echo -------------------------

srun --output=${LOG_DIR}/node_log/node-%t.out sh submit-node.sh

...