Phân tích lỗi không khớp chiều (Dimension Mismatch)
Nó thường xảy ra ngay sau một thay đổi cấu hình "nhanh". Bạn thay đổi một model HuggingFace cục bộ bằng một lời gọi OpenAI API, khởi động lại dịch vụ, và pipeline RAG (Retrieval-Augmented Generation) của bạn lập tức bị sập. Đây không phải là lỗi trong logic của bạn; đó là một thất bại cơ bản về mặt toán học.
AssertionError: Embedding dimension 1536 does not match index dimension 768.
FAISS là một thư viện C++ hiệu suất cao, coi dữ liệu của bạn như các điểm trong một lưới đa chiều. Nó yêu cầu sự nhất quán nghiêm ngặt. Nếu bạn xây dựng index của mình bằng all-mpnet-base-v2 (768 chiều) nhưng cố gắng truy vấn nó bằng text-embedding-3-small của OpenAI (1536 chiều), việc so sánh là bất khả thi về mặt toán học. Bạn không thể so sánh một điểm trong không gian 768 chiều với một điểm trong không gian 1536 chiều.
Xác định điểm xung đột
Trước khi xóa dữ liệu của mình, hãy xác định chính xác kích thước chiều của hai thành phần. Lỗi này thường xuất hiện vì đối tượng embeddings được truyền vào FAISS.load_local() khác với đối tượng đã được sử dụng trong quá trình FAISS.save_local().
Bước 1: Kiểm tra Index đã lưu
Bạn không cần chạy truy vấn để tìm các yêu cầu của index. Hãy kiểm tra trực tiếp tệp .faiss bằng thư viện nền tảng:
import faiss
# Tải tệp index thô
index = faiss.read_index("index_path/index.faiss")
print(f"Index dimension: {index.d}")
# Output: Index dimension: 768
Bước 2: Xác minh Model đang hoạt động
Tiếp theo, hãy xác nhận xem code hiện tại của bạn thực sự đang tạo ra cái gì. Một dòng code duy nhất có thể xác minh kích thước đầu ra của nhà cung cấp embedding:
from langchain_openai import OpenAIEmbeddings
# Khởi tạo model hiện tại của bạn
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
test_vector = embeddings.embed_query("test")
print(f"Model dimension: {len(test_vector)}")
# Output: Model dimension: 1536
Nếu các con số 768 và 1536 (hoặc 384 và 1024) không khớp nhau, lỗi AssertionError sẽ tiếp tục tồn tại.
Cách khắc phục
Bạn có hai lựa chọn: hạ cấp model của mình để khớp với index cũ hoặc xây dựng lại index để tận dụng model mới. Hầu hết các nhà phát triển chọn xây dựng lại nếu họ đang nâng cấp lên một stack LLM mạnh mẽ hơn.
Tùy chọn A: Xây dựng lại Index (Khuyến nghị khi nâng cấp)
Không có cách nào để "thay đổi kích thước" một vector hiện có. Nếu bạn chuyển từ một model 768 chiều sang một model 1536 chiều, bạn phải thực hiện re-embed các tài liệu nguồn của mình. Đây là một sự khởi đầu mới cho vector store của bạn.
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
# 1. Sử dụng model 1536 chiều mới
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# 2. Xử lý các tài liệu nguồn
loader = TextLoader("knowledge_base.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=50)
docs = text_splitter.split_documents(documents)
# 3. Tạo và lưu index mới
vectorstore = FAISS.from_documents(docs, embeddings)
vectorstore.save_local("faiss_index_v2")
Tùy chọn B: Quay lại Model cũ
Nếu việc re-indexing hàng triệu tài liệu quá tốn kém hoặc mất thời gian, bạn phải sử dụng model gốc. Ví dụ, nếu index được xây dựng bằng all-MiniLM-L6-v2, hãy đảm bảo loader của bạn sử dụng chính xác model đó:
from langchain_community.embeddings import HuggingFaceEmbeddings
# Model này tạo ra 384 chiều
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
# Tải index 384 chiều tương ứng
vectorstore = FAISS.load_local("legacy_index", embeddings, allow_dangerous_deserialization=True)
Tối ưu hóa Pipeline RAG cho tương lai
Ngăn chặn các lỗi sập này tiếp cận môi trường production bằng cách thêm một bước kiểm tra xác thực trong quá trình khởi động. Script này so sánh kích thước của model và index trước khi ứng dụng bắt đầu chấp nhận các truy vấn:
def safe_load_faiss(folder_path, embeddings_model):
vectorstore = FAISS.load_local(folder_path, embeddings_model, allow_dangerous_deserialization=True)
# Kiểm tra một embedding mẫu với index
model_dim = len(embeddings_model.embed_query("validation"))
index_dim = vectorstore.index.d
if model_dim != index_dim:
raise ValueError(f"Critical Mismatch: Model is {model_dim}D, but Index is {index_dim}D.")
return vectorstore
Những điểm lưu ý quan trọng
- Đặt tên rõ ràng: Đặt tên cho các thư mục index của bạn theo tên model và số chiều (ví dụ:
vector_store_openai_1536) để tránh nhầm lẫn. - Lưu trữ Metadata: Giữ một tệp
config.jsonbên cạnh index FAISS của bạn để ghi lại tên model, phiên bản và số lượng chiều. - Chú ý các giá trị mặc định:
text-embedding-3-smallcủa OpenAI mặc định là 1536, nhưng nó có thể được cắt ngắn. Luôn chỉ định số chiều nếu bạn không sử dụng giá trị mặc định.

