비디오 트랜스코딩 인스턴스의 성능 테스트
카카오클라우드는 실시간 비디오 트랜스코딩 작업 수행 시 뛰어난 성능을 제공하도록 설계된 인스턴스 유형 중 하나로
vt1a
인스턴스를 제공합니다. 이 튜토리얼 에서는,vt1a
인스턴스에 예제 스크립트를 실행하여 병렬로 H.264 확장자 파일에서 HEVC 확장자 파일로 트랜스코딩하는 과정을 인스턴스 크기 별로 확인하고 결과를 비교합니다.
- 예상 소요 시간: 30 ~ 60분
- 권장 운영 체제: Ubuntu
- 리전: kr-central-2
시작하기 전에
이 튜토리얼에서는 카카오클라우드의 비디오 트랜스코딩 인스턴스 유형인 vt1a
를 사용하여, 하나의 동영상 파일을 입력받아 여러 개의 트랜스코딩된 파일을 출력하는 방법을 설명합니다. 이 과정에서 하나의 입력 파일을 여러 번 사용하여, 입력 파일 수에 따라 각각 트랜스코딩된 결과 파일을 생성하는 예제를 다룹니다.
vt1a
인스턴스 크기 별로 할당되어 있는 U30 가속기 카드 수 및 이에 따른 디바이스 수에 따라 병렬 처리 가능한 수가 달라지며, 이에 따라 처리 완료 시간이 다른 것을 확인할 수 있습니다
사전 작업
VPC 및 서브넷 생성
인스턴스를 생성하기 전, 인스턴스가 생성될 VPC 및 서브넷을 생성해야 합니다. VPC와 서브넷이 없다면, VPC 생성, 서브넷 생성 문서를 참고하여 VPC 및 서브넷을 생성합니다.
키 페어 생성
인스턴스에 SSH 연결로 접근하기 위해 키 페어가 생성되어 있어야 합니다. 키 페어 생성 문서를 참고하여 키 페어를 생성한 후, 생성 시점에 발급되는 프라이빗 키를 보관합니다.
보안 그룹 생성
인스턴스 레벨에서 높은 보안을 확보하기 위해 보안 그룹을 생성하고, 적절한 인바운드 규칙을 추가해야 합니다. 보안 그룹 생성 문서를 참고하여 보안 그룹을 생성하고 인바운드 규칙에 아래의 규칙을 추가합니다.
프로토콜 | 출발지 | 포트 번호 | 규칙 설명 |
---|---|---|---|
TCP | {사용자 공인 IP}/32 | 22 | 로컬 PC에서 이 보안 그룹에 연결된 인스턴스에 SSH 접근을 허용 |
다음 버튼을 클릭하면 현재 사용 중인 나의 퍼블릭 IP를 확인할 수 있습니다.
작업 순서
Step 1. 인스턴스 생성
-
카카오클라우드 콘솔에서 Beyond Compute Service의 Virtual Machine 메뉴를 선택합니다.
-
인스턴스 메뉴로 이동 후, [인스턴스 생성] 버튼을 클릭합니다.
-
아래와 같이
vt1a
인스턴스를 생성합니다. 본 예제에서는vt1a
인스턴스의 크기에 따른 성능 비교를 하기 위해vt1a.4xlarge
,vt1a.8xlarge
,vt1a.32xlarge
를 각각 생성합니다.항목 설정값 기본 정보 - 이름: 사용자 지정
- 개수: 1개이미지 기본 탭에서 Ubuntu 22.04 선택
- 하단의 SDK 지원 운영체제 정보 참고인스턴스 유형 vt1a.4xlarge
,vt1a.8xlarge
,vt1a.32xlarge
각각 생성볼륨 - 루트 볼륨: 기본값 유지 키 페어 사전 작업에서 미리 생성한 키 페어 선택 네트워크 - VPC: 사전 작업에서 미리 생성한 VPC 선택
- 서브넷: 사전 작업에서 미리 생성한 서브넷 선택
- 보안 그룹: 사전 작업에서 미리 생성한 보안 그룹 선택
2024년 기준 최신 버전인 Xilinx Video SDK 3.0가 정상적으로 작동되는 검증된 운영체제 및 커널 버전은 아래와 같습니다.
- Ubuntu 22.04(Kernel 5.15)
- Ubuntu 20.04.4 (Kernel 5.13)
- Ubuntu 20.04.3 (Kernel 5.11)
- Ubuntu 20.04.1 (Kernel 5.4)
- Ubuntu 20.04.0 (Kernel 5.4)
- Ubuntu 18.04.5 (Kernel 5.4)
Step 2. 퍼블릭 IP 연결
앞서 생성한 인스턴스 각각에 퍼블릭 IP를 할당 및 연결하여 SSH 접근이 가능하도록 설정합니다.
-
카카오클라우드 콘솔에서 Beyond Compute Service의 Virtual Machine 메뉴를 선택합니다.
-
인스턴스 메뉴로 이동 후, 생성한 인스턴스의 [더 보기] 메뉴 > 퍼블릭 IP 연결을 선택합니다.
- 필요에 따라 퍼블릭 IP 생성 및 관리을 참고하여 퍼블릭 IP를 생성한 후, 퍼블릭 IP 할당 방식을 선택합니다.
-
[확인] 버튼을 선택하여 퍼블릭 IP 연결 작업을 완료합니다. 각각의 인스턴스에서 동일하게 작업합니다.
Step 3. SSH 연결
인스턴스에 Xilinx Video SDK를 설치하기 위해 SSH로 연결 및 접근이 필요합니다. 이 작업 과정을 설명합니다.
-
카카오클라우드 콘솔에서 Beyond Compute Service의 Virtual Machine 메뉴를 선택합니다.
-
인스턴스 메뉴로 이동 후, 생성한 인스턴스의 **[더 보기] > [SSH 연결]**을 선택하여 SSH 연결을 위한 명령어 및 설정 등을 확인합니다.
-
로컬 PC에서 아래의 SSH 연결을 위한 명령어를 입력하여 각 인스턴스에 SSH 연결을 시도합니다. SSH 연결에 대한 자세한 설명은 인스턴스 연결을 참고하시기 바랍니다.
ssh -i ${key-pair-name}.pem ubuntu@${public-ip-addr}
매개변수 설명 key-pair-name 인스턴스 생성 시 지정한 키 페어에 대한 프라이빗 키 파일명 public-ip-addr 인스턴스에 할당 및 연결된 퍼블릭 IP 주소
Step 4. Xilinx Video SDK 설치
Xilinx Video SDK는 사용자가 Xilinx 비디오 코덱 유닛의 하드웨어 가속 기능을 원활하게 활용하여 라이브 스트리밍 비디오와 같은 고밀도 실시간 비디오 트랜스코딩을 지원하기 위한 소프트웨어 스택입니다. 이 SDK에는 Xilinx 디바이스용 비디오 트랜스코딩 플러그인을 통합하는 사전 컴파일 버전의 FFmpeg 및 GSreamer가 포함되어 있으며, 이를 통해 비디오 인코딩 및 디코딩, 비디오 업스케일링을 포함한 하드웨어 가속화를 지원합니다.
비디오 트랜스코딩 예제를 실행하기 전 Xilinx Video SDK의 설치가 필요하며, Xilinx Video SDK 설치 가이드를 따라 설치를 진행합니다.
Step 5. 런타임 환경 설정
런타임 환경 설정을 참고하여 런타임 환경 설정을 완료합니다.
이제 예제를 실행할 수 있는 환경 구성이 완료되었습니다.
인스턴스 크기 별 성능 비교
vt1a
인스턴스에서 지원하는 Alveo U30 가속기 카드의 가속 H.264/AVC 및 H.265/HEVC 코덱은 이전 세대 모바일 핸드셋부터 초고해상도 디스플레이가 탑재된 최신 세대 핸드셋에 이르기까지, 광범위한 최종 사용자 디바이스에서 효율적으로 디코딩할 수 있는 SDR(8비트) 및 HDR(10비트) 프로파일을 지원합니다.
이 U30 가속기 카드에는 카드당 2개씩 Xilinx 디바이스가 설정되어 있습니다. 각각 vt1a.4xlarge
, vt1a.8xlarge
, vt1a.32xlarge
각각 1, 2, 8개의 U30 가속기 카드가 있으며, 따라서 디바이스 수는 각각 2, 4, 16개입니다.
본 튜토리얼에서 사용하는 스크립트 파일은 하나의 샘플 H.264 파일을 사용자가 지정한 수만큼 입력 파일 수로 하여 디바이스 수에 맞춰 할당한 뒤, HEVC로 트랜스코딩 시 이를 병렬로 처리합니다. 트랜스코딩 처리된 결과 파일은 지정된 디렉터리에 입력 파일 수만큼 저장되며, 작업 완료까지 걸린 시간을 표시합니다.
vt1a
인스턴스의 크기 별로 최대 디바이스 수가 다르므로 동일한 입력 수일 때 병렬 처리 가능한 수가 달라지게 되며, 각각의 처리 시간을 비교함으로써 크기 별 병렬 처리 시 성능 차이를 확인할 수 있습니다.
예제 스크립트 코드
아래 코드의 매개변수 값을 사용자 환경에 맞춰 적절히 수정한 다음 스크립트 파일로 저장합니다. 예제 스크립트에서 입력 파일로 사용하는 파일은 아래의 링크에서 다운로드 받을 수 있습니다. 본 튜토리얼에서는 이 스크립트 파일명을 ffmpg_basic.sh
로 지정하였습니다.
#!/bin/bash
if [[ $# -ne 2 ]]; then
echo "[ERROR] Incorrect arguments supplied."
echo "Usage: $(basename $0) <the number of input(int)> <the number of device(int)>"
exit 1
fi
INPUT_FILE=$HOME/videos/sample_4kp60fps.h264 # 예제용 샘플 H.264 파일의 경로 및 파일명
INPUT_CNT=$1 # 해당 파일을 병렬 처리시킬 수
INPUT_ARR=$(seq 0 $((INPUT_CNT-1))) # 결과값 파일명에 들어가는 순차적 인덱스 번호로, INPUT_CNT 값을 기반으로 처리
DEV_CNT=$2 # 사용할 디바이스 수
DETECTED_DEV_CNT=`xbutil examine | grep -c xilinx_u30`
if [[ ${DEV_CNT} -gt ${DETECTED_DEV_CNT} ]]; then
echo "[ERROR] Incorrect arguments supplied."
echo "<the number of device(int)> can not be larger than the actual number of devices(${DETECTED_DEV_CNT})"
exit 1
fi
DEV_IDX=0
for i in ${INPUT_ARR}
do
if [ ${DEV_IDX} -eq ${DEV_CNT} ]; then
echo
echo "All Device is in use. Waiting until devices is available..."
wait
sleep 1
echo
DEV_IDX=0
fi
OUTPUT_FILE=$HOME/videos/output_hevc_${i}.mp4 # 처리 후 결과 파일이 저장되는 경로 및 파일명
LOG_FILE=$HOME/logs/log${i}.out # 처리 후 결과 파일에 대한 로그 파일이 저장되는 경로 및 파일명
rm -rf ${OUTPUT_FILE} ${LOG_FILE}
cmd="nohup ffmpeg -xlnx_hwdev ${DEV_IDX} -c:v mpsoc_vcu_h264 -i ${INPUT_FILE} -f mp4 -c:v mpsoc_vcu_hevc -y ${OUTPUT_FILE} > ${LOG_FILE} 2>&1 &"
echo $cmd
echo
eval "$cmd"
DEV_IDX=$((DEV_IDX + 1))
done
wait
echo
echo "All Done."
매개변수 | 설명 |
---|---|
INPUT_FILE | 예제용 샘플 H.264 파일의 경로 및 파일명 - 예: INPUT_FILE=$HOME/videos/sample_4kp60fps.h264 |
INPUT_CNT | 해당 파일을 병렬 처리시킬 수 - 예: INPUT_CNT=8 |
DEV_CNT | 사용할 디바이스 수 - 예: DEV_CNT=2 ⚠️ vt1a 인스턴스 크기에 따른 최대 디바이스 수를 초과하여 입력할 수 없으며, 초과된 값을 입력할 경우 에러가 발생 |
OUTPUT_FILE | 처리 후 결과 파일이 저장되는 경로 및 파일명 - 예: OUTPUT_FILE=$HOME/videos/output_hevc_${i}.mp4 ⚠️ 이 값에 명시된 디렉터리(예: $HOME/videos)가 사전에 생성되어 있어야 정상적으로 스크립트 실행이 완료됨 |
LOG_FILE | 처리 후 결과 파일에 대한 로그 파일이 저장되는 경로 및 파일명 - 예: $HOME/logs/log${i}.out ⚠️ 이 값에 명시된 디렉터리(예: $HOME/logs)가 사전에 생성되어 있어야 정상적으로 스크립트 실행이 완료됨 |
Step 1. vt1a.4xlarge에서 예제 스크립트 실행
-
vt1a.4xlarge
인스턴스에서 예제 스크립트 실행 전 아래와 같이 각 매개변수의 값들을 설정합니다.매개변수 설명 INPUT_FILE $HOME/videos/sample_4kp60fps.h264 INPUT_CNT 16 DEV_CNT 2 -
vt1a.4xlarge
에서 사용 가능한 최대 디바이스 수는 2개이므로 16개의 입력 파일을 2개씩 총 8번에 나눠서 처리합니다. 아래와 같이 입력하여 매개변수 값의 지정 및 스크립트 파일의 실행을 진행합니다.INPUT_CNT=16
DEV_CNT=2
time bash ffmpg_basic.sh ${INPUT_CNT} ${DEV_CNT} -
스크립트 파일이 실행 후 완료되면 아래와 같은 결과값이 출력됩니다.
...
All Done.
real 1m17.518s
user 0m3.671s
sys 0m6.926s정보 설명 real
실제 경과 시간(Actual elapsed time)을 의미하며, 스크립트가 실행 후 완료될 때까지 순수하게 측정된 전체 실행 시간을 의미 user
프로세스 내부의 사용자 모드 코드(User-mode code)가 실행되는 데 걸린 CPU 시간을 의미하며, 커널 밖에서 연산이 진행되는 동안 CPU가 소비한 누적 시간의 합 sys
프로세스 내부의 커널에서 실행된 CPU 시간을 의미하며, 커널 내부에서 시스템 호출(System call)에 사용된 CPU 시간만을 의미 -
전체 입력 파일에 대한 실제 처리 시간을 확인해야 하므로
real
값을 확인합니다.
Step 2. vt1a.8xlarge에서 예제 스크립트 실행
-
위와 동일하게 설정을 완료 후 스크립트 파일을 실행합니다. 이때 설정할 매개변수 중
DEV_CNT
값을 아래와 같이 변경합니다.매개변수 설명 INPUT_FILE INPUT_FILE=$HOME/videos/sample_4kp60fps.h264 INPUT_CNT 16 DEV_CNT 4 -
아래와 같이 매개변수 값을 지정하고, 스크립트 파일을 실행합니다.
INPUT_CNT=16
DEV_CNT=4
time bash ffmpg_basic.sh ${INPUT_CNT} ${DEV_CNT} -
결과값을 확인합니다. 실제 경과 시간(
real
)을 비교 시,vt1a.4xlarge
에 비해 약 2배 빠르게 처리되었음을 확인할 수 있습니다....
All Done.
real 0m38.295s
user 0m3.726s
sys 0m7.019s
Step 3. vt1a.32xlarge에서 예제 스크립트 실행
-
위와 동일하게 설정을 완료 후 스크립트 파일을 실행합니다. 이때 설정할 매개변수 중
DEV_CNT
값을 아래와 같이 변경합니다.매개변수 설명 INPUT_FILE INPUT_FILE=$HOME/videos/sample_4kp60fps.h264 INPUT_CNT 16 DEV_CNT 16 -
아래와 같이 매개변수 값을 지정하고, 스크립트 파일을 실행합니다.
INPUT_CNT=16
DEV_CNT=16
time bash ffmpg_basic.sh ${INPUT_CNT} ${DEV_CNT} -
결과값을 확인합니다. 실제 경과 시간(
real
)을 비교 시,vt1a.4xlarge
에 비해 약 8배,vt1a.8xlarge
에 비해 약 4배 빠르게 처리되었음을 확인할 수 있습니다....
All Done.
real 0m10.246s
user 0m3.907s
sys 0m8.851s
결과 분석
vt1a.4xlarge
, vt1a.8xlarge
, vt1a.32xlarge
에서 16개의 입력 파일에 대해 각각의 최대 디바이스 수를 사용하여 출력 파일로 트랜스코딩 처리하는 데 걸린 실제 경과 시간에 대한 결과값을 비교하면 아래와 같습니다.
인스턴스 크기 | 처리 시간 |
---|---|
vt1a.4xlarge | 약 77초 |
vt1a.8xlarge | 약 38초 |
vt1a.32xlarge | 약 10초 |
vt1a.32xlarge
는 총 디바이스 수와 입력 파일 수가 동일하므로, 16개의 입력 파일을 모두 동시에 병렬로 처리했습니다.
반면, vt1a.4xlarge
와 vt1a.8xlarge
는 각각 디바이스 수가 2개, 4개이기 때문에 동시에 처리할 수 있는 입력 파일 수는 제한됩니다. 이로 인해 파일들을 여러 그룹으로 나누어 처리해야 하며, 4xlarge
는 2개씩 8번, 8xlarge는 4개씩 4번에 걸쳐 파일을 순차적으로 처리했습니다. 이로 인해 처리 시간이 증가한 것을 확인할 수 있습니다.
고밀도 실시간 비디오 트랜스코딩 시 목적 및 용도에 따라 병렬 처리가 요구되는 워크로드에서는 vt1a.32xlarge
와 같이 디바이스 수가 충분히 많은 큰 크기의 인스턴스의 사용을 권장합니다.
고밀도 실시간 비디오 트랜스코딩 작업에서는 병렬 처리의 효율이 매우 중요합니다. 따라서 동시에 더 많은 파일을 처리할 수 있는 vt1a.32xlarge
와 같은 더 큰 인스턴스를 사용하는 것이 효율적입니다.