Ngừng tua video thủ công: Xây dựng hệ thống Video RAG bằng cách trích xuất Keyframe và Tìm kiếm Vector

AI tutorial - IT technology blog
AI tutorial - IT technology blog

Cơn ác mộng mang tên “Tua video”

Tháng trước, tôi đã lãng phí cả một buổi chiều chỉ để tìm một đoạn clip dài 30 giây. Đội ngũ của tôi quản lý một thư viện gồm hơn 1.000 giờ video hội thảo kỹ thuật, và trưởng dự án cần một khoảnh khắc cụ thể: giây phút chính xác khi một kỹ sư vẽ sơ đồ cơ sở dữ liệu mới trên bảng trắng.

Việc tua video thủ công (scrubbing) là một kẻ thù của năng suất. Trong khi chúng ta có những công cụ tìm kiếm văn bản tuyệt vời, thì video vẫn là một “hộp đen”. Bạn có thể tìm kiếm theo tên tệp hoặc thẻ tag, nhưng các công cụ tiêu chuẩn không thể “nhìn thấy” một khái niệm hình ảnh như “sơ đồ microservices trên bảng trắng vật lý”.

Đây là lúc Retrieval-Augmented Generation (RAG) truyền thống gặp bế tắc. Hầu hết chúng ta đều đã quen với việc nạp file PDF vào vector store để LLM truy vấn. Video phức tạp hơn nhiều. Nó có tính đa chiều, tính thời gian và cực kỳ nặng về lưu trữ. Làm chủ Video RAG là bước tiếp theo tất yếu nếu bạn muốn vượt qua các chatbot cơ bản và xây dựng các công cụ AI có tác động lớn cho doanh nghiệp.

Tại sao tìm kiếm thông thường bỏ qua 99% dữ liệu video

Vấn đề cốt lõi nằm ở cách chúng ta biểu diễn video. Đối với máy tính, tệp .mp4 hoặc .mkv chỉ là một luồng byte được nén. Metadata như “Tiêu đề” và “Thời lượng” không cho bạn biết gì về nội dung thực tế bên trong các khung hình.

Việc chuyển soạn (transcription) có giúp ích, nhưng không phải là liều thuốc vạn năng. Sử dụng các công cụ như Whisper để chuyển âm thanh thành văn bản chỉ ghi lại được những gì được nói. Nếu người thuyết trình trình bày một lỗi UI hoặc chỉ vào một biểu đồ mà không mô tả bằng lời, hệ thống RAG dựa trên văn bản của bạn sẽ không bao giờ tìm thấy nó. Bạn hoàn toàn mất đi ngữ cảnh hình ảnh.

Chúng ta đang phải đối mặt với hai thách thức chính: Mật độ dữ liệuKhoảng cách ngữ nghĩa. Một video 60-fps tiêu chuẩn tạo ra 3.600 hình ảnh mỗi phút. Xử lý mọi khung hình qua một mô hình AI là một thảm họa về chi phí và tính toán. Hầu hết các khung hình gần như giống hệt với các khung hình trước đó, tạo ra sự dư thừa khổng lồ trong cơ sở dữ liệu vector của bạn.

Ba chiến lược xử lý dữ liệu video

Tôi đã đánh giá ba cách khác nhau để giúp thư viện video của chúng tôi có thể tìm kiếm được. Mỗi cách đều có mức giá và sự đánh đổi về độ chính xác riêng.

1. Lối tắt Chuyển soạn (Transcription)

Phương pháp này sử dụng Whisper của OpenAI để lập chỉ mục âm thanh. Nó nhanh và rẻ. Tuy nhiên, nó “mù” về mặt hình ảnh. Nếu bạn đang xem một bài hướng dẫn Photoshop và người hướng dẫn nói “Nhấp vào đây”, công cụ tìm kiếm sẽ không biết “đây” là bảng layer hay công cụ brush.

2. Phương pháp Duyệt cạn (Brute Force)

Trong kịch bản này, bạn trích xuất mọi khung hình và chạy chúng qua một mô hình thị giác như CLIP. Với 1.000 giờ video ở tốc độ 30fps, bạn đang nhìn vào 108 triệu khung hình. Nếu mỗi vector có 512 chiều, chỉ riêng chỉ mục của bạn đã tăng lên hơn 200GB. Nó có độ chính xác cao nhưng chi phí truy vấn cực kỳ đắt đỏ.

3. “Điểm cân bằng lý tưởng”: Trích xuất Keyframe

Đây là phương pháp chúng tôi cuối cùng đã đưa vào triển khai thực tế. Chúng tôi sử dụng các thuật toán để phát hiện các điểm cắt cảnh hoặc chuyển động đáng kể, chỉ trích xuất các “Keyframe”. Bằng cách bỏ qua các khung hình dư thừa, chúng tôi giảm lượng dữ liệu lên đến 98% trong khi vẫn giữ nguyên ý nghĩa ngữ nghĩa.

Xây dựng Pipeline Video RAG

Một pipeline sẵn sàng cho sản xuất đòi hỏi ba giai đoạn riêng biệt: Trích xuất thông minh, Embedding đa phương thức và Tìm kiếm Vector.

Bước 1: Trích xuất Keyframe thông minh

Đừng chỉ lấy một khung hình sau mỗi năm giây. Hãy sử dụng PySceneDetect để tìm các thay đổi nội dung thực tế. Điều này đảm bảo bạn bắt được khoảnh khắc chính xác khi một trang slide thay đổi hoặc một diễn giả mới bước lên sân khấu.

import cv2
from scenedetect import detect, ContentDetector

def extract_keyframes(video_path, threshold=27.0):
    # Phát hiện các cảnh dựa trên thay đổi nội dung thay vì khoảng thời gian cố định
    scene_list = detect(video_path, ContentDetector(threshold=threshold))
    
    keyframes = []
    cap = cv2.VideoCapture(video_path)
    
    for i, scene in enumerate(scene_list):
        start_frame = scene[0].get_frames()
        cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)
        success, frame = cap.read()
        if success:
            filename = f"scene_{i}_at_{scene[0].get_seconds()}s.jpg"
            cv2.imwrite(filename, frame)
            keyframes.append({"file": filename, "timestamp": scene[0].get_seconds()})
            
    cap.release()
    return keyframes

Bước 2: Tạo Embedding đa phương thức (Multimodal Embeddings)

Bây giờ chúng ta cần làm cho những khung hình này có thể tìm kiếm được. Tôi sử dụng CLIP (Contrastive Language-Image Pre-training). Nó ánh xạ hình ảnh và văn bản vào cùng một không gian toán học. Điều này cho phép người dùng nhập truy vấn văn bản để tìm hình ảnh tương ứng.

from sentence_transformers import SentenceTransformer
from PIL import Image

# Sử dụng mô hình ViT-B-32 để cân bằng giữa tốc độ và độ chính xác
model = SentenceTransformer('clip-ViT-B-32')

def generate_embeddings(image_path):
    img = Image.open(image_path)
    return model.encode(img)

Bước 3: Tìm kiếm Vector với Qdrant

Chúng tôi lưu trữ các embedding này trong Qdrant. Nó xử lý các vector đa chiều một cách hiệu quả và cho phép chúng tôi đính kèm metadata, như timestamp chính xác, trực tiếp vào vector.

from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct

client = QdrantClient("localhost", port=6333)

# Chúng ta đóng gói timestamp và video ID vào payload để dễ dàng truy xuất
points = [
    PointStruct(
        id=idx, 
        vector=emb["vector"].tolist(), 
        payload={"timestamp": emb["timestamp"], "video_id": "workshop_2024_01"}
    ) 
    for idx, emb in enumerate(processed_data)
]

client.upsert(collection_name="video_intelligence", points=points)

Kết quả cuối cùng

Khi ai đó tìm kiếm “database architecture diagram” (sơ đồ kiến trúc cơ sở dữ liệu), hệ thống sẽ chuyển văn bản đó thành một vector CLIP. Sau đó, nó quét Qdrant và trả về các timestamp chính xác. Tôi thường thêm một “vùng đệm ngữ cảnh” 5 giây trước timestamp để người dùng không bị nhảy vào giữa một câu nói.

Lời khuyên cuối cùng cho DevOps

Mở rộng hệ thống này không chỉ nằm ở mã nguồn; nó còn nằm ở hạ tầng. Một pipeline sẵn sàng cho sản xuất đòi hỏi ba giai đoạn riêng biệt: Trích xuất thông minh, Embedding đa phương thức và Tìm kiếm Vector. 1.000 giờ video 1080p tương đương với khoảng 2,5TB dữ liệu thô. Chạy CLIP trên khối lượng đó đòi hỏi sức mạnh GPU đáng kể. Luôn xử lý video một cách bất đồng bộ. Sử dụng hàng đợi công việc như Celery hoặc RabbitMQ để người dùng của bạn không phải nhìn chằm chằm vào biểu tượng tải trong khi máy chủ đang xử lý một tệp tải lên 2GB.

Bằng cách chuyển từ tìm kiếm văn bản cơ bản sang Video RAG, bạn biến các tệp video “chết” thành một cơ sở tri thức có cấu trúc và có thể tìm kiếm được. Đây là một sự nâng cấp khổng lồ cho bất kỳ công ty nào dựa vào video để làm tài liệu hướng dẫn hoặc đào tạo.

Share: