All Products
Search
Document Center

Function Compute:Praktik terbaik untuk pemrosesan audio dan video

Last Updated:Apr 01, 2026

Instans Function Compute yang dipercepat GPU memungkinkan Anda menjalankan transkoding video berbasis FFmpeg secara skala besar tanpa perlu mengelola driver GPU, versi CUDA, atau kluster perangkat keras. Panduan ini akan memandu Anda melalui proses penyebaran fungsi transkoding yang dipercepat GPU menggunakan Serverless Devs dan Python, dengan contoh konversi dari MP4 ke FLV.

Kapan menggunakan akselerasi GPU

Akselerasi GPU memberikan manfaat paling signifikan ketika pekerjaan transkoding diperkirakan berjalan lebih dari beberapa menit atau ketika Anda memerlukan beberapa aliran output dari satu input. Skenario spesifik meliputi:

  • Transkoding 1080p dan resolusi lebih tinggi: Video H.264 1080p berdurasi 2 menit membutuhkan waktu lebih dari 3 menit pada CPU tetapi kurang dari 10 detik pada GPU — percepatan hingga 20x.

  • Output multi-aliran (1:N): Menghasilkan 3 resolusi output secara simultan membutuhkan waktu kurang dari 6 menit pada CPU tetapi sekitar 45 detik pada GPU.

  • Pipeline sensitif latensi: Streaming langsung sosial, kelas daring, dan telemedisin memerlukan pengiriman secara real-time atau mendekati real-time.

Untuk pekerjaan yang selesai jauh di bawah satu menit pada CPU, overhead penyediaan instans GPU mungkin lebih besar daripada manfaat percepatannya.

Format codec yang didukung

Instans yang dipercepat GPU didasarkan pada arsitektur Turing dan menggunakan GPU NVIDIA T4.

Encoding

Format
H.264 (AVCHD) YUV 4:2:0
H.264 (AVCHD) YUV 4:4:4
H.264 (AVCHD) Lossless
H.265 (HEVC) 4K YUV 4:2:0
H.265 (HEVC) 4K YUV 4:4:4
H.265 (HEVC) 4K Lossless
H.265 (HEVC) 8K
HEVC 10-bit
HEVC B-frame

Decoding

FormatBit depths
MPEG-18-bit
MPEG-28-bit
VC-18-bit
VP88-bit
VP98-bit, 10-bit, 12-bit
H.264 (AVCHD)8-bit, 10-bit, 12-bit
H.265 (HEVC) 4:2:08-bit, 10-bit, 12-bit
*H.265 (HEVC) 4:4:48-bit, 10-bit, 12-bit

Tolok ukur kinerja

Pengujian berikut menggunakan video sumber H.264 berdurasi 2 menit 5 detik (1920x1080, 25 fps, 4.085 Kb/s; audio: aac (LC), 44.100 Hz, stereo, fltp) pada mesin dengan CPU identik (Xeon® Platinum 8163 4C, RAM 16 GB) — satu dengan GPU T4, satu tanpa GPU. Versi FFmpeg: git-2020-08-12-1201687.

Transkoding 1:1 (1 input, 1 output)

ResolusiTanpa GPUDengan GPU
H264 1920x1080 (Full HD, 1080p)3 menit 19,3 dtk9,4 dtk
H264 1280x720 (HD, 720p)2 menit 3,7 dtk5,8 dtk
H264 640x480 (480p)1 menit 1,0 dtk5,8 dtk
H264 480x360 (360p)44,4 dtk5,7 dtk

Transkoding 1:N (1 input, 3 output: 1080p + 720p + 480p)

Tanpa GPUDengan GPU
5 menit 58,7 dtk45,3 dtk

Cara kerja

Fungsi berjalan di dalam kontainer kustom yang dibangun berdasarkan gambar FFmpeg yang telah diaktifkan NVIDIA. Saat dipanggil, fungsi tersebut:

  1. Mengunduh video sumber dari bucket Object Storage Service (OSS).

  2. Menjalankan FFmpeg untuk mentranskode video. Dalam mode GPU, FFmpeg memindahkan proses decoding dan encoding ke perangkat keras NVIDIA menggunakan CUDA — flag -hwaccel cuda -hwaccel_output_format cuda menyimpan frame yang telah didekode di memori GPU, sehingga menghindari transfer CPU-GPU sebelum proses encoding. Flag h264_nvenc menginstruksikan FFmpeg untuk menggunakan encoder perangkat keras NVIDIA untuk output H.264, bukan encoder perangkat lunak. Tanpa flag tersebut, FFmpeg akan kembali menggunakan encoding perangkat lunak pada CPU.

  3. Mengunggah hasil transkoding ke OSS.

Prasyarat

Sebelum memulai, pastikan Anda telah memiliki:

  • Keanggotaan grup DingTalk (ID grup: 11721331). Untuk bergabung, berikan nama organisasi Anda, ID akun Alibaba Cloud, wilayah target (misalnya, China (Shenzhen)), dan detail kontak.

  • Instans Container Registry Edisi Perusahaan di wilayah yang sama dengan instans yang dipercepat GPU Anda. Edisi Personal dapat digunakan, tetapi Edisi Perusahaan direkomendasikan. Lihat Buat instans Container Registry Edisi Perusahaan.

  • Namespace dan repository image di instans tersebut. Lihat Buat namespace dalam dokumentasi Container Registry. Kemudian buat repository image di instans yang sama.

  • Binari FFmpeg yang dikompilasi dengan dukungan GPU NVIDIA. Gunakan salah satu berikut:

  • Berkas audio dan video yang telah diunggah ke bucket OSS di wilayah yang sama. Fungsi memerlukan akses baca dan tulis ke objek bucket tersebut. Lihat Unggah objek untuk instruksi pengunggahan dan Ubah ACL bucket untuk pengaturan izin.

Perintah transkoding FFmpeg

Semua contoh di bawah menggunakan gambar Docker willprice/nvidia-ffmpeg.

Tanpa akselerasi GPU

Output tunggal (1:1)

docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg \
  -y -i input.mp4 -c:v h264 -vf scale=1920:1080 -b:v 5M output.mp4

Output ganda (1:N)

docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg \
  -y -i input.mp4 \
  -c:a copy -c:v h264 -vf scale=1920:1080 -b:v 5M output_1080.mp4 \
  -c:a copy -c:v h264 -vf scale=1280:720  -b:v 5M output_720.mp4 \
  -c:a copy -c:v h264 -vf scale=640:480   -b:v 5M output_480.mp4

Dengan akselerasi GPU

Output tunggal (1:1)

docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg \
  -y -hwaccel cuda -hwaccel_output_format cuda \
  -i input.mp4 -c:v h264_nvenc -vf scale_cuda=1920:1080:1:4 -b:v 5M output.mp4

Output ganda (1:N)

docker run --rm -it --volume $PWD:/workspace --runtime=nvidia willprice/nvidia-ffmpeg \
  -y -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \
  -c:a copy -c:v h264_nvenc -vf scale_npp=1920:1080 -b:v 5M output_1080.mp4 \
  -c:a copy -c:v h264_nvenc -vf scale_npp=1280:720  -b:v 5M output_720.mp4 \
  -c:a copy -c:v h264_nvenc -vf scale_npp=640:480   -b:v 5M output_480.mp4

Parameter utama

ParameterDeskripsi
-hwaccel cudaMemilih akselerator perangkat keras CUDA untuk decoding
-hwaccel_output_format cudaMenyimpan frame yang telah didekode di memori GPU, menghindari transfer CPU-GPU sebelum encoding
-c:v h264_nvencMenggunakan encoder H.264 perangkat keras NVIDIA
-c:a copyMenyalin aliran audio tanpa melakukan re-encoding
-b:v 5MMengatur bitrate output menjadi 5 Mb/s

Sebarkan fungsi GPU dengan Serverless Devs

Sebelum memulai, instal Serverless Devs dan Docker. Lalu ikuti langkah-langkah untuk mengonfigurasi Serverless Devs dengan kredensial Anda.

Prosedur

  1. Buat proyek.

    fc-gpu-prj
    ├── code
    │   ├── app.py        # Kode fungsi
    │   └── Dockerfile    # Dockerfile gambar
    ├── README.md
    └── s.yaml            # Konfigurasi penyebaran

    Struktur proyek yang dihasilkan:

    fc-gpu-prj
    ├── code
    │   ├── app.py        # Kode fungsi
    │   └── Dockerfile    # Dockerfile gambar
    ├── README.md
    └── s.yaml            # Konfigurasi penyebaran
  2. Masuk ke direktori proyek.

    cd fc-gpu-prj
  3. Edit file konfigurasi. s.yaml — perbarui wilayah, nama layanan, dan URI gambar kontainer sesuai lingkungan Anda. Parameter utama terkait GPU adalah instanceType: fc.gpu.tesla.1 dan gpuMemorySize: 8192.

    edition: 1.0.0
    name: container-demo
    access: default
    vars:
      region: cn-shenzhen
    services:
      customContainer-demo:
        component: devsapp/fc
        props:
          region: ${vars.region}
          service:
            name: tgpu_ffmpeg_service
            internetAccess: true
          function:
            name: tgpu_ffmpeg_func
            description: test gpu for ffmpeg
            handler: not-used
            timeout: 600
            caPort: 9000
            instanceType: fc.gpu.tesla.1
            gpuMemorySize: 8192
            cpu: 4
            memorySize: 16384
            diskSize: 512
            runtime: custom-container
            customContainerConfig:
              # Prasyarat:
              # 1. Buat namespace "demo" dan repository "gpu-transcoding_s" di Container Registry.
              # 2. Tingkatkan tag (misalnya, v0.1 -> v0.2) saat memperbarui dan menyebarkan ulang.
              image: registry.cn-shanghai.aliyuncs.com/demo/gpu-transcoding_s:v0.1
            codeUri: ./code

    Untuk daftar lengkap parameter YAML, lihat Spesifikasi YAML. app.py — fungsi ini mengunduh video sumber dari OSS, mentranskode dengan FFmpeg (menggunakan GPU atau CPU berdasarkan header TRANS-MODE), lalu mengunggah hasilnya kembali ke OSS. Ganti nilai placeholder src_url dan dst_url dengan URL objek OSS aktual Anda.

    # -*- coding: utf-8 -*-
    from __future__ import print_function
    from http.server import HTTPServer, BaseHTTPRequestHandler
    import json
    import sys
    import logging
    import os
    import time
    import urllib.request
    import subprocess
    
    class Resquest(BaseHTTPRequestHandler):
        def download(self, url, path):
            print("enter download:", url)
            f = urllib.request.urlopen(url)
            with open(path, "wb") as local_file:
                local_file.write(f.read())
    
        def upload(self, url, path):
            print("enter upload:", url)
            headers = {
                'Content-Type': 'application/octet-stream',
                'Content-Length': os.stat(path).st_size,
            }
            req = urllib.request.Request(url, open(path, 'rb'), headers=headers, method='PUT')
            urllib.request.urlopen(req)
    
        def trans(self, input_path, output_path, enable_gpu):
            print("enter trans input:", input_path, " output:", output_path, " enable_gpu:", enable_gpu)
    
            cmd = ['ffmpeg', '-y', '-i', input_path, "-c:a", "copy", "-c:v", "h264", "-b:v", "5M", output_path]
            if enable_gpu:
                cmd = ["ffmpeg", "-y", "-hwaccel", "cuda", "-hwaccel_output_format", "cuda", "-i", input_path, "-c:v", "h264_nvenc", "-b:v", "5M", output_path]
    
            try:
                subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
            except subprocess.CalledProcessError as exc:
                print('\nreturncode:{}'.format(exc.returncode))
                print('\ncmd:{}'.format(exc.cmd))
                print('\noutput:{}'.format(exc.output))
                print('\nstderr:{}'.format(exc.stderr))
                print('\nstdout:{}'.format(exc.stdout))
    
        def trans_wrapper(self, enable_gpu):
            src_url = "https://your.domain/input.mp4"  # Ganti dengan URL objek OSS Anda (akses baca diperlukan)
            dst_url = "https://your.domain/output.flv" # Ganti dengan URL objek OSS Anda (akses tulis diperlukan)
            src_path = "/tmp/input_c.flv"
            dst_path = "/tmp/output_c.mp4"
    
            if enable_gpu:
                src_url = "https://your.domain/input.mp4"  # Ganti dengan URL objek OSS Anda (akses baca diperlukan)
                dst_url = "https://your.domain/output.flv" # Ganti dengan URL objek OSS Anda (akses tulis diperlukan)
                src_path = "/tmp/input_g.flv"
                dst_path = "/tmp/output_g.mp4"
    
            local_time = time.time()
            self.download(src_url, src_path)
            download_time = time.time() - local_time
    
            local_time = time.time()
            self.trans(src_path, dst_path, enable_gpu)
            trans_time = time.time() - local_time
    
            local_time = time.time()
            self.upload(dst_url, dst_path)
            upload_time = time.time() - local_time
    
            data = {'result':'ok', 'download_time':download_time, 'trans_time':trans_time, 'upload_time':upload_time}
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(data).encode())
    
        def pong(self):
            data = {"function":"trans_gpu"}
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(data).encode())
    
        def dispatch(self):
            mode = self.headers.get('TRANS-MODE')
    
            if mode == "ping":
                self.pong()
            elif mode == "gpu":
                self.trans_wrapper(True)
            elif mode == "cpu":
                self.trans_wrapper(False)
            else:
                self.pong()
    
        def do_GET(self):
            self.dispatch()
    
        def do_POST(self):
            self.dispatch()
    
    if __name__ == '__main__':
        host = ('0.0.0.0', 9000)
        server = HTTPServer(host, Resquest)
        print("Starting server, listen at: %s:%s" % host)
        server.serve_forever()

    Dockerfile — membangun gambar kontainer dari gambar dasar NVIDIA FFmpeg dan menambahkan runtime Python.

    FROM registry.cn-shanghai.aliyuncs.com/serverless_devs/nvidia-ffmpeg:latest
    WORKDIR /usr/src/app
    RUN apt-get update --fix-missing
    RUN apt-get install -y python3
    RUN apt-get install -y python3-pip
    COPY . .
    ENTRYPOINT [ "python3", "-u", "/usr/src/app/app.py" ]
    EXPOSE 9000
  4. Bangun gambar kontainer.

    s build --dockerfile ./code/Dockerfile
  5. Sebarkan ke Function Compute.

    Jika Anda menjalankan s deploy lagi dengan nama layanan dan fungsi yang sama, jalankan use local terlebih dahulu untuk menggunakan konfigurasi lokal.
    s deploy
  6. Buat instans yang disediakan agar fungsi GPU siap menangani permintaan tanpa latensi cold start.

    s provision put --target 1 --qualifier LATEST
  7. Verifikasi bahwa instans yang disediakan sudah siap.

    s provision get --qualifier LATEST

    Instans siap digunakan ketika current sama dengan 1. Contoh output:

    [2021-12-14 08:45:24] [INFO] [S-CLI] - Start ...
    [2021-12-14 08:45:24] [INFO] [FC] - Getting provision: tgpu_ffmpeg_service.LATEST/tgpu_ffmpeg_func
    customContainer-demo:
     serviceName:      tgpu_ffmpeg_service
     functionName:      tgpu_ffmpeg_func
     qualifier:       LATEST
     resource:        188077086902****#tgpu_ffmpeg_service#LATEST#tgpu_ffmpeg_func
     target:         1
     current:        1
     scheduledActions:    (empty array)
     targetTrackingPolicies: (empty array)
     currentError:
  8. Panggil fungsi tersebut. Periksa versi yang telah disebarkan:

    s invoke

    Transkode dengan CPU:

    s invoke -e '{"method":"GET","headers":{"TRANS-MODE":"cpu"}}'

    Transkode dengan GPU:

    s invoke -e '{"method":"GET","headers":{"TRANS-MODE":"gpu"}}'
  9. Setelah selesai, lepas instans yang disediakan untuk menghentikan biaya.

    s provision put --target 0 --qualifier LATEST

Sebarkan fungsi GPU dari konsol

  1. Siapkan gambar kontainer.

    1. Buat instans Container Registry Edisi Perusahaan (direkomendasikan) atau instans Edisi Personal. Lihat Buat instans Container Registry Edisi Perusahaan.

    2. Buat namespace dan repository image di instans tersebut. Lihat Buat namespace dalam dokumentasi Container Registry. Lalu ikuti langkah-langkah untuk membuat repository image di instans yang sama.

    3. Ikuti instruksi Docker di Konsol Container Registry untuk mendorong app.py dan Dockerfile (dari direktori /code Serverless Devs) ke repository image.

    db-acr-docker

  2. Buat layanan. Lihat bagian Buat layanan.

  3. Buat fungsi. Lihat Buat fungsi kontainer kustom.

    Atur Instance Type ke GPU Instance dan Request Handler Type ke Process HTTP Requests.
  4. Tingkatkan periode timeout eksekusi. Transkoding CPU untuk video berdurasi 2 menit membutuhkan waktu lebih dari 100 detik — jauh di atas timeout default 60 detik.

    1. Temukan fungsi tersebut dan klik Configure di kolom Actions.

    2. Di bagian Environment Information, tingkatkan Execution Timeout Period lalu klik Save.

    db-gpu-time

  5. Konfigurasikan instans yang dipercepat GPU yang disediakan. Setelah pembuatan, periksa daftar aturan dan pastikan bahwa Current Reserved Instances sesuai dengan jumlah target Anda.

    1. Di halaman detail fungsi, klik tab Auto Scaling, lalu klik Create Rule.

    2. Konfigurasikan parameter untuk menyediakan instans yang dipercepat GPU lalu klik Create. Lihat Konfigurasikan aturan penskalaan otomatis untuk detailnya.

    db-gpu-reserved

  6. Uji fungsi dengan cURL.

    1. Di halaman detail fungsi, klik tab Triggers untuk mendapatkan titik akhir pemicu.

    2. Jalankan perintah berikut:

      Periksa versi yang telah disebarkan:

      curl -v "https://tgpu-ff-console-tgpu-ff-console-ajezot****.cn-shenzhen.fcapp.run"
      {"function": "trans_gpu"}

      Transkode dengan CPU:

      curl "https://tgpu-ff-console-tgpu-ff-console-ajezot****.cn-shenzhen.fcapp.run" -H 'TRANS-MODE: cpu'
      {"result": "ok", "upload_time": 8.75510573387146, "download_time": 4.910430669784546, "trans_time": 105.37688875198364}

      Transkode dengan GPU:

      curl "https://tgpu-ff-console-tgpu-ff-console-ajezotchpx.cn-shenzhen.fcapp.run" -H 'TRANS-MODE: gpu'
      {"result": "ok", "upload_time": 8.313958644866943, "download_time": 5.096682548522949, "trans_time": 8.72346019744873}

Hasil

Akses hasil transkoding dari browser Anda menggunakan nama domain OSS. Contohnya:

https://cri-zbtsehbrr8******-registry.oss-cn-shenzhen.aliyuncs.com/output.flv

Ganti nama domain dengan titik akhir OSS aktual Anda.

Langkah selanjutnya