REC

Hệ gợi ý và tìm kiếm ngữ nghĩa cho ứng dụng nội dung

Bốn tầng của một hệ gợi ý đa phương thức: từ phân tích nội dung thô, sinh biểu diễn vector, tới tìm kiếm lai và xếp hạng nhiều nguồn.

hệ gợi ýtìm kiếm ngữ nghĩaembeddinglọc cộng tácANN

Một ứng dụng nghe nhạc cần trả lời hai câu hỏi liên tục: người này nên nghe gì tiếp theo, và khi họ gõ vào ô tìm kiếm thì trả về cái gì. Nghe như hai tính năng, nhưng chúng dùng chung phần lớn hạ tầng bên dưới — và chính phần hạ tầng ấy là nội dung chủ yếu của bài này.

Hệ thống đã dựng

NGUỒN VÀO TẦNG 1 VÀ 2 TẦNG 3 VÀ 4 Tệp âm thanh nội dung thô Siêu dữ liệu và lời tiêu đề, nghệ sĩ, lời bài hát Tương tác phát, thích, bỏ qua 1. Phân tích nội dung sinh năm nhóm nhãn mô tả 2. Sinh biểu diễn bốn không gian vector bốn chỉ mục lân cận gần đúng Lọc cộng tác và mô hình chuỗi huấn luyện ngoại tuyến 3. Tìm kiếm lai nhánh vector cộng nhánh từ khoá 4. Gợi ý nhiều nguồn nội dung, cộng tác, trình tự
Bốn tầng phụ thuộc một chiều. Tầng sinh biểu diễn là nút thắt: hai tầng cuối chỉ đọc các chỉ mục do nó tạo ra.

Kiến trúc gồm bốn module xếp thành chuỗi phụ thuộc một chiều, chạy như một dịch vụ riêng bên cạnh backend nghiệp vụ.

Tầng một: phân tích nội dung

Đầu vào là tệp âm thanh thô. Đầu ra là các nhãn mô tả, chia thành năm nhóm: thể loại, tâm trạng, nhạc cụ, đặc điểm giọng hát, và ngôn ngữ.

Điểm đáng nói ở tầng này là bộ nhãn không được bịa ra. Mỗi nhóm neo vào một hệ phân loại có sẵn: tâm trạng theo mô hình vòng tròn cảm xúc của Russell, chia mặt phẳng thành bốn góc phần tư theo hai trục mức độ kích thích và sắc thái tích cực hay tiêu cực; nhạc cụ theo hệ Hornbostel–Sachs, phân theo cơ chế phát âm thành dây, hơi, màng rung, tự thân vang và điện tử; ngôn ngữ lấy tập con của một bộ nhận dạng ngôn ngữ có sẵn để khớp với mô hình dùng ở bước sau.

KÍCH THÍCH CAO KÍCH THÍCH THẤP TIÊU CỰC TÍCH CỰC hân hoan phấn khích giận dữ lo âu chán nản buồn êm dịu thư thái nhãn mới
Hai trục biến bộ nhãn tâm trạng thành một không gian có toạ độ, nên một nhãn mới có chỗ để rơi vào thay vì phải chèn thêm vào cuối một danh sách.

Việc neo vào hệ phân loại có sẵn nghe như chi tiết nhỏ, nhưng nó quyết định khả năng mở rộng: khi cần thêm nhãn, có một cấu trúc để đặt nhãn mới vào đúng chỗ, thay vì một danh sách phẳng mà ai cũng có thể thêm bừa.

Về mô hình, tầng này dùng hai mạng chạy song song. Một mạng phân loại đa nhãn dựa trên kiến trúc transformer cho phổ âm thanh, với bốn đầu ra riêng cho bốn nhóm nhãn đầu. Một mạng riêng chuyên cho nhận dạng ngôn ngữ, dựa trên kiến trúc thường dùng trong xử lý tiếng nói. Tách hai việc thay vì gộp vào một mạng nhiều đầu là có chủ ý: nhận dạng ngôn ngữ dựa vào đặc trưng ngữ âm, còn phân loại thể loại dựa vào đặc trưng hoà âm và nhịp điệu — ép chúng dùng chung phần thân dễ khiến hai tác vụ cản nhau.

Tầng hai: sinh biểu diễn và lập chỉ mục

Đây là nút thắt của toàn hệ thống. Mỗi bài hát được biến thành bốn vector nằm trong bốn không gian khác nhau:

  • Vector âm thanh, lấy từ trạng thái ẩn của mạng phân tích phổ, tính trung bình theo trục thời gian.
  • Vector thẻ mô tả, sinh bằng một mô hình nhúng văn bản đa ngữ. Điểm thú vị ở đây: thay vì mã hoá các nhãn thành vector nhị phân, hệ thống ghép chúng thành một câu tiếng Việt tự nhiên — đại ý “Tiêu đề X. Nghệ sĩ Y. Thể loại A. Tâm trạng B. Nhạc cụ C” — rồi mới đưa vào mô hình nhúng. Nhờ vậy một truy vấn kiểu “bài buồn có tiếng guitar” khớp được với nội dung mà không cần từ điển ánh xạ thủ công giữa từ khoá và nhãn.
  • Vector lời bài hát, cũng từ mô hình nhúng văn bản, chạy trên phần lời.
  • Vector hành vi, lấy từ ma trận thừa số của mô hình lọc cộng tác.
CÁCH ĐÃ CHỌN CÁCH ĐÃ BỎ Nhãn rời thể loại, tâm trạng nhạc cụ, giọng hát Câu tiếng Việt tự nhiên Tiêu đề X. Thể loại A. Tâm trạng B. Nhạc cụ C. Mô hình nhúng văn bản đa ngữ Vector dày khớp truy vấn ngôn ngữ tự nhiên Mã hoá nhị phân mỗi nhãn một chiều 0/1 Vector thưa không khớp truy vấn ngôn ngữ tự nhiên không qua mô hình nào
Câu tự nhiên là bước đệm đưa truy vấn của người dùng và mô tả nội dung về chung một không gian; mã hoá nhị phân không có bước đệm đó.

Bốn vector này được lập chỉ mục riêng bằng một thư viện tìm kiếm lân cận gần đúng, dùng cấu trúc đồ thị phân tầng. Ý tưởng của cấu trúc này là xây đồ thị nhiều lớp, lớp trên thưa để nhảy xa, lớp dưới dày để tinh chỉnh — nhờ đó thời gian tìm kiếm tăng theo hàm lô-ga-rít thay vì tuyến tính với số lượng mục.

LỚP TRÊN ít điểm, cạnh dài LỚP GIỮA dày hơn, cạnh ngắn hơn LỚP ĐÁY đủ điểm, cạnh ngắn nhất điểm vào đích
Mỗi lần xuống một lớp, phạm vi còn phải xét lại thu nhỏ. Số lớp tăng theo lô-ga-rít của số điểm, nên số bước cũng vậy.

Tầng ba: tìm kiếm lai

Một truy vấn đi song song qua hai nhánh. Nhánh vector đưa truy vấn vào cùng không gian với nội dung rồi tìm lân cận. Nhánh từ khoá khớp chuỗi trên tiêu đề, tên nghệ sĩ và các nhãn. Hai nhánh cho ra hai danh sách, và một bước hợp điểm gộp lại cùng hai yếu tố phụ là độ phổ biến và độ mới.

Hệ thống hỗ trợ cả truy vấn bằng văn bản lẫn truy vấn bằng một đoạn âm thanh — trường hợp sau đi thẳng vào chỉ mục vector âm thanh.

Tầng bốn: gợi ý nhiều nguồn

Ba nguồn ứng viên chạy độc lập rồi hợp lại.

Dựa trên nội dung. Lấy trung bình vector của những bài người dùng đã thích để tạo hồ sơ sở thích, rồi tìm lân cận của hồ sơ đó. Với người dùng mới chưa thích bài nào, hồ sơ được dựng từ các bài phổ biến nhất — một cách xử lý khởi đầu nguội đơn giản và rẻ.

Lọc cộng tác. Dùng thuật toán bình phương tối thiểu luân phiên trên ma trận tương tác. Ý tưởng: phân rã ma trận người dùng nhân nội dung thành tích của hai ma trận thừa số nhỏ hơn, rồi luân phiên cố định một bên để giải bên còn lại — mỗi bước là một bài bình phương tối thiểu có nghiệm đóng, nên hội tụ nhanh và song song hoá được.

TƯƠNG TÁC NGƯỜI DÙNG NỘI DUNG BƯỚC LUÂN PHIÊN × Cố định V, giải U mỗi bước có nghiệm đóng Cố định U, giải V rồi đổi vai hai bên phần lớn ô còn trống giải bằng luân phiên
Hai ma trận thừa số cộng lại nhỏ hơn hẳn ma trận gốc, và chúng dày đặc — đó là chỗ những ô còn trống được điền vào.

Theo trình tự. Một mạng transformer nhận chuỗi nội dung người dùng vừa tiêu thụ và dự đoán mục tiếp theo, có mặt nạ nhân quả để mỗi vị trí chỉ nhìn được về quá khứ.

Điểm chung của cả ba: chúng trả về ứng viên kèm điểm số, và một hàm hợp điểm tuyến tính gộp lại thành bảng xếp hạng cuối, cộng thêm độ phổ biến và độ mới.

Tín hiệu ngầm: biến hành vi thành con số

Có một chi tiết thiết kế đáng mang đi nơi khác. Dữ liệu tương tác thô chỉ có các sự kiện rời rạc — phát, thích, bỏ thích. Trước khi đưa vào mô hình, mỗi sự kiện được quy về một trọng số thực theo vài quy tắc:

  • Bỏ qua sớm, tức nghe chưa được bao nhiêu đã chuyển bài, mang giá trị âm — nó là tín hiệu không thích, chứ không phải trung tính.
  • Nghe gần trọn được nhân thêm hệ số: tín hiệu tích cực mạnh hơn nghe nửa chừng.
  • Tương tác tự tìm đến được đánh giá cao hơn tương tác đến từ gợi ý, vì nó phản ánh ý định chủ động.
  • Tương tác gần đây có trọng số cao hơn tương tác cũ, giảm dần theo thời gian.
0 TRỌNG SỐ MỘT SỰ KIỆN ÂM DƯƠNG SUY GIẢM THEO THỜI GIAN bỏ qua sớm nghe nửa chừng nghe gần trọn đến từ gợi ý tự tìm đến cao hơn gần đây lâu rồi cùng hành vi, càng cũ càng nhẹ
Bảng đã thích hay chưa chỉ có hai giá trị. Thang này liên tục, có phần âm, và còn nhạt dần khi sự kiện lùi về quá khứ.

Bốn quy tắc này mã hoá được những thứ mà một bảng “đã thích hay chưa” không có. Đây là phần chuyển từ dữ liệu sự kiện sang tín hiệu học được, và nó thường quyết định chất lượng nhiều hơn việc chọn mô hình.

Hạ tầng

Dịch vụ AI viết bằng Python với FastAPI, phơi ra bốn điểm cuối tương ứng bốn module. Backend nghiệp vụ viết bằng Java gọi sang. Dữ liệu nằm trên một cơ sở dữ liệu tài liệu, kèm một lớp bộ nhớ đệm cho kết quả gợi ý và tìm kiếm. Trọng số mô hình được tải sẵn vào ảnh máy ảo lúc dựng thay vì tải lúc chạy.

Một chi tiết vận hành đáng ghi: tác vụ nặng được tách ra chạy như tiến trình con riêng thay vì chạy trong tiến trình web. Lý do là mô hình chiếm nhiều bộ nhớ, và nếu chạy chung thì một yêu cầu nặng có thể làm chết worker đang phục vụ mọi người dùng khác.

Kiến thức nền: vì sao bài toán này khó

Không gian tìm kiếm quá lớn để chấm điểm trực tiếp

Với danh mục cỡ vài nghìn mục, có thể chấm điểm mọi mục cho mọi người dùng. Với vài triệu thì không. Đây là ràng buộc định hình toàn bộ kiến trúc của các hệ thống lớn, và là lý do tồn tại của tìm kiếm lân cận gần đúng: chấp nhận bỏ sót một phần nhỏ kết quả đúng để đổi lấy tốc độ tăng theo bậc.

Ba họ phương pháp, ba điểm mạnh khác nhau

Dựa trên nội dung hoạt động ngay cả với mục hoàn toàn mới, vì nó chỉ cần đặc trưng của chính mục đó. Nhược điểm là nó có xu hướng gợi ý quanh quẩn những thứ giống cái đã biết, khó đưa người dùng tới sở thích mới.

Lọc cộng tác phát hiện được những liên hệ mà không đặc trưng nội dung nào giải thích nổi — hai bài hát chẳng liên quan gì về âm nhạc nhưng cùng được một nhóm người yêu thích. Đổi lại, nó cần lịch sử tương tác, nên thất bại với mục mới và người dùng mới.

Theo trình tự nắm bắt ý định trong phiên hiện tại, thứ mà hai họ trên bỏ qua: người vừa nghe ba bài ru con có ngữ cảnh khác hẳn người vừa nghe ba bài tập gym, dù hồ sơ dài hạn giống nhau.

Không họ nào thay thế được họ nào, và đó là lý do các hệ thống thực tế đều lai.

Khởi đầu nguội là bài toán riêng

Một mục mới chưa ai nghe thì lọc cộng tác không có gì để nói về nó. Một người dùng mới cũng vậy. Các hướng xử lý phổ biến: dựa vào đặc trưng nội dung cho mục mới, dựa vào nhân khẩu học cho người dùng mới, hoặc chủ động đưa mục mới vào một phần nhỏ lưu lượng để thu thập tín hiệu ban đầu.

Ngành công nghiệp làm việc này ra sao

Đối chiếu với các tài liệu thiết kế hệ thống quy mô lớn, có bốn điểm đáng học.

Kiến trúc nhiều tầng lọc dần. Chuẩn phổ biến là hai đến ba tầng. Tầng sinh ứng viên rẻ và thiên về độ phủ, thường chạy nhiều bộ sinh song song với tiêu chí khác nhau — độ liên quan, độ phổ biến, độ mới — rồi gộp lại, thu từ hàng triệu mục xuống vài trăm. Tầng chấm điểm đắt hơn và giàu đặc trưng hơn, thu tiếp xuống vài chục. Tầng sắp xếp lại áp các quy tắc nghiệp vụ: đa dạng nguồn, lọc nội dung đã xem, chèn yếu tố khám phá, cân bằng lợi ích các bên trong một thị trường hai chiều.

Toàn bộ danh mục Sinh ứng viên nhiều bộ sinh chạy song song rẻ, thiên về độ phủ Chấm điểm đắt, giàu đặc trưng Sắp xếp lại quy tắc nghiệp vụ còn một tập nhỏ còn nhỏ hơn nữa danh sách cuối TỐI ƯU CHO ĐỘ PHỦ thà thừa còn hơn bỏ sót TỐI ƯU CHO ĐỘ CHÍNH XÁC xếp đúng thứ tự TỐI ƯU CHO TRẢI NGHIỆM đa dạng, lọc đã xem, khám phá
Mỗi tầng đổi độ phủ lấy độ chính xác. Chia tầng còn cho phép đo riêng từng khúc, nhờ đó biết khúc nào đang là nút thắt.

Việc chia tầng không chỉ để nhanh. Nó còn cho phép cải thiện từng phần độc lập, và cho phép đo xem tầng nào đang là nút thắt.

Hai họ mô hình cho hai tầng. Phân rã ma trận nhanh và rẻ nhưng không dùng được đặc trưng ngoài định danh. Mạng hai tháp — một tháp mã hoá người dùng, một tháp mã hoá nội dung, cùng chiếu vào một không gian — nhận được đặc trưng phong phú và xử lý người dùng mới tốt hơn, đổi lại tốn kém hơn. Cách ghép thường thấy là dùng mô hình nhẹ ở tầng sinh ứng viên và mô hình nặng ở tầng chấm điểm.

Chỉ số ngoại tuyến phải nối được với hành vi thật. Các chỉ số xếp hạng như nDCG tính đến vị trí: một kết quả đúng ở hạng nhất giá trị hơn cùng kết quả đó ở hạng mười. Bên cạnh đó là các chỉ số trực tuyến — tỷ lệ nhấp, thời gian xem, tỷ lệ hoàn thành. Điều quan trọng là chọn chỉ số ngoại tuyến nào dự báo tốt cho chỉ số trực tuyến mà tổ chức thực sự quan tâm.

Một biến thể đáng chú ý là entropy chéo chuẩn hoá: nó chia hiệu năng mô hình cho hiệu năng của baseline luôn dự đoán tỷ lệ trung bình. Giá trị lớn hơn một nghĩa là mô hình tệ hơn baseline — chỉ số này tự phơi bày thất bại thay vì để người đọc phải suy ra.

Tìm kiếm xuyên phương thức cần không gian chung. Muốn truy vấn bằng văn bản chạm tới nội dung âm thanh, hai bên phải nằm trong cùng một không gian vector, và điều đó chỉ có được khi mô hình được huấn luyện tương phản trên các cặp văn bản–âm thanh. Đặt cạnh nhau hai bộ mã hoá riêng biệt rồi cộng điểm không tạo ra khả năng đó — nó chỉ cho phép so văn bản với phần văn bản mô tả nội dung, đúng như cách hệ thống ở trên hoạt động.

Vài điều rút ra

Bước biến sự kiện thành tín hiệu quan trọng hơn vẻ ngoài của nó. Công thức quy đổi tương tác thành trọng số — phân biệt bỏ qua với nghe trọn, tự tìm với được gợi ý, gần đây với đã lâu — là phần mang lại nhiều giá trị nhất trên mỗi dòng mã trong toàn hệ thống.

Ghép nhiều nguồn điểm cần chuẩn hoá trước khi cộng. Điểm từ ba nguồn thường có thang đo hoàn toàn khác nhau: một bên là tương đồng nằm trong khoảng đơn vị, một bên là tích vô hướng không chặn, một bên là xác suất trên hàng nghìn lớp nên luôn rất nhỏ. Cộng thẳng có trọng số sẽ khiến nguồn có thang nhỏ gần như không đóng góp gì, dù trọng số danh nghĩa không nhỏ. Chuẩn hoá về cùng thang, hoặc hợp nhất theo thứ hạng, là bước bắt buộc.

CỘNG THẲNG ba thang khác hẳn nhau CHUẨN HOÁ TRƯỚC hoặc hợp nhất theo hạng gần như biến mất tương đồng cosin tích vô hướng xác suất tương đồng cosin tích vô hướng xác suất
Trọng số danh nghĩa không quyết định đóng góp thật; thang đo mới quyết định. Chuẩn hoá là bước trả quyền đó lại cho trọng số.

Thước đo khoảng cách phải khớp với cách vector được tạo ra. Chỉ mục lân cận mặc định thường dùng khoảng cách Euclid, trong khi phần lớn biểu diễn ngữ nghĩa được thiết kế để so bằng cosin. Nếu không chuẩn hoá độ dài vector trước khi lập chỉ mục, thứ hạng sẽ bị chi phối bởi độ dài chứ không chỉ bởi hướng.

Sinh biểu diễn nên đi trước mọi thứ khác. Trong chuỗi bốn tầng, ba tầng sau đều đọc chỉ mục do tầng hai tạo ra. Khi dựng lại một hệ thống tương tự, đây là thứ tự bắt buộc — và cũng là chỗ đáng đầu tư nhất, vì chất lượng biểu diễn đặt trần cho mọi thứ phía sau.