Hướng dẫn Tinker: Tinh chỉnh LLM với Thinking Machines Lab
Hướng dẫn thực hành triển khai LoRA qua Tinker AI để huấn luyện Qwen3-8B trên dữ liệu Chain-of-Thought (CoT) tài chính, tối ưu cho khả năng khái quát hóa.
Tinh chỉnh các mô hình ngôn ngữ lớn thường đồng nghĩa với việc phải xử lý hạ tầng GPU phân tán, quản lý lỗi cụm và gỡ lỗi các script huấn luyện phức tạp. Tinker ra đời để giải quyết những điều đó.
Được Thinking Machines Lab của Mira Murati phát hành ngày 1 tháng 10, 2025, Tinker là một API huấn luyện xử lý toàn bộ phần phức tạp về hạ tầng trong khi vẫn trao cho bạn toàn quyền kiểm soát thuật toán và dữ liệu. Bạn chỉ cần viết các script Python đơn giản với bốn hàm cốt lõi, và Tinker sẽ chạy chúng trên GPU phân tán cho nhiều mô hình mã nguồn mở như Llama 70B hoặc Qwen 235B.
Nền tảng sử dụng tinh chỉnh Low-Rank Adaptation (LoRA) để giảm chi phí và hỗ trợ mọi thứ từ học có giám sát đến học tăng cường. Các nhóm nghiên cứu tại Princeton, Stanford và Berkeley đã sử dụng cho công việc của họ.
Trong hướng dẫn này, tôi sẽ đưa bạn qua các bước cài đặt Tinker, hiểu API của nó, và tinh chỉnh một mô hình Hỏi & Đáp tài chính hoàn chỉnh bằng mô hình nền Qwen3-8B. Nếu bạn muốn tìm hiểu thêm về tinh chỉnh với bài thực hành, tôi khuyến nghị xem khóa học về Tinh chỉnh với Llama 3.
Tinker là gì?
Thinking Machines Lab xây dựng Tinker cho những ai muốn tùy biến cách mô hình học mà không cần trở thành chuyên gia hạ tầng.
Ai đang dùng Tinker?
Nền tảng hướng tới ba nhóm:
Nhà nghiên cứu khám phá phương pháp huấn luyện mới
Nhà phát triển xây dựng sản phẩm AI cần hành vi tùy chỉnh
Người xây dựng muốn kết quả chất lượng sản xuất mà không cần nguồn lực doanh nghiệp.
Mỗi nhóm đều có nhu cầu chung: họ biết mô hình cần làm gì, nhưng các giao diện tinh chỉnh tiêu chuẩn không cho họ đủ quyền kiểm soát.
Ví dụ, các nhóm học thuật có thể dùng để thử nghiệm thuật toán mới. Một phòng thí nghiệm hóa học có thể muốn huấn luyện mô hình theo các mẫu lập luận theo miền không phù hợp với các khuôn mẫu instruction-tuning điển hình. Một startup xây dựng bot cố vấn tài chính có thể dùng mô hình để tuân thủ các định dạng đầu ra và chuỗi lập luận cụ thể.
Điểm chung của các trường hợp này là họ cần sửa đổi chính quá trình huấn luyện, không chỉ thay bộ dữ liệu.
Điều gì khiến Tinker khác biệt?
Đa số nền tảng tối ưu cho một trong hai thứ: dễ dùng hoặc linh hoạt. Cách tiếp cận của Tinker là hai điều này không nhất thiết xung đột. Nền tảng cho bạn truy cập cấp thấp vào huấn luyện qua bốn thao tác cốt lõi, nhưng tự động xử lý mọi thứ còn lại:
Kiểm soát vòng lặp huấn luyện: Viết hàm mất mát riêng, chiến lược tích lũy gradient hoặc mẫu lấy mẫu.
Cập nhật mô hình: Chỉ định chính xác cách trọng số thay đổi trong tối ưu hóa.
Đánh giá: Tạo đầu ra hoặc tính xác suất tại bất kỳ thời điểm nào trong huấn luyện.
Quản lý trạng thái: Lưu và tiếp tục huấn luyện với toàn quyền kiểm soát những gì được lưu trữ.
Tinker cung cấp các khả năng này qua bốn nguyên thủy API mà bạn sẽ học trong phần thực hành.
Điều này hiệu quả vì phần lớn độ phức tạp huấn luyện đến từ hạ tầng, không phải bản thân thuật toán. Chạy một vòng lặp huấn luyện tùy chỉnh trên laptop khá đơn giản. Chạy nó trên 100 GPU với khả năng phục hồi lỗi và điều phối tài nguyên thì khó. Tinker xử lý phần thứ hai để bạn tập trung vào phần đầu.
Vị trí của Tinker trong hệ sinh thái
Hệ sinh thái công cụ AI có thể chia đại khái thành ba lớp: nhà cung cấp điện toán đám mây cung cấp GPU thô, nền tảng quản lý chạy các quy trình dựng sẵn, và framework giúp bạn xây hệ thống huấn luyện từ đầu. Tinker nằm giữa nền tảng quản lý và framework. Bạn có nhiều quyền kiểm soát hơn so với các nền tảng như Hugging Face AutoTrain, nhưng ít việc hạ tầng hơn so với tự dựng cụm trên Google Cloud Platform (GCP).
Giá Tinker và tín dụng
Tinker dùng biểu giá minh bạch theo token, biến thiên theo kích thước mô hình và loại thao tác. Huấn luyện Qwen3-8B tốn $0,40 cho mỗi triệu token. Tin vui: người dùng mới nhận $150 tín dụng sau khi được duyệt khỏi danh sách chờ, dư sức cho vài lần huấn luyện thử nghiệm như trong hướng dẫn này.
Ví dụ với Tinker: Tinh chỉnh Qwen3-8B cho Hỏi & Đáp tài chính
Trong phần này, tôi sẽ hướng dẫn bạn xây dựng một quy trình tinh chỉnh hoàn chỉnh bằng API của Tinker. Chúng ta sẽ tinh chỉnh Qwen3-8B trên dữ liệu hỏi đáp tài chính bằng LoRA, học cả bốn nguyên thủy API cốt lõi đồng thời quan sát thực hành tốt trong môi trường sản xuất.
Lưu ý quan trọng: Tinker hiện đang ở giai đoạn beta với quyền truy cập theo danh sách chờ. Nếu bạn đã có quyền, bạn có thể làm theo và chạy mã. Nếu bạn đang trong danh sách chờ, bạn vẫn có thể đọc để hiểu quá trình tinh chỉnh với Tinker đơn giản ra sao. Khi có quyền, bạn sẽ sẵn sàng bắt tay ngay.
Kết quả huấn luyện và chọn checkpoint
Hãy xem kết quả huấn luyện trước. Hiểu chuyện gì đã xảy ra sẽ giúp bạn nhận ra các mẫu này khi chạy job tinh chỉnh của riêng mình.
Chúng tôi tinh chỉnh Qwen3-8B trên bộ dữ liệu FinCoT, một bộ dữ liệu lập luận tài chính theo chuỗi suy nghĩ, bằng LoRA với rank 32. Sau khi lọc các chuỗi không dài quá 10.000 token, chúng tôi còn 7.244 mẫu huấn luyện và 500 mẫu để đánh giá.
Huấn luyện chạy 904 vòng lặp qua bốn epoch, mất khoảng ba giờ để hoàn tất, trong khi Tinker xử lý toàn bộ điều phối GPU phân tán.
Một epoch là một lượt duyệt toàn bộ dữ liệu huấn luyện. Vì có 226 batch mỗi epoch (7.244 mẫu chia cho batch size 32), bốn epoch tổng cộng 904 vòng lặp.
Phân tích kết quả huấn luyện
Biểu đồ sau theo dõi ba chỉ số: training loss (xanh), validation loss (đỏ), và learning rate (xanh lá).
Giai đoạn đầu (vòng lặp 0-400) trông ổn: cả training và validation loss cùng giảm mạnh, từ trên 1,4 xuống dưới 0,8 và duy trì cách nhau khoảng 0,1.
Giai đoạn này cho thấy mô hình đang học hiệu quả các mẫu có khả năng khái quát trong dữ liệu. Learning rate (đường xanh lá) tăng dần mượt trong 200 vòng lặp đầu, khi warmup ổn định huấn luyện.
Khoảng vòng lặp 400-600, tình hình thay đổi. Training loss tiếp tục giảm, nhưng validation loss chững quanh 0,75-0,8, nới rộng khoảng cách tới 0,13 khi mô hình bắt đầu overfit. Từ 600-900, sự phân kỳ trở nên rõ ràng: training loss giảm mạnh xuống 0,39 trong khi validation loss tăng lên 0,8, cho thấy mô hình đã chuyển từ học mẫu lập luận sang ghi nhớ ví dụ.
Mẫu hình này khá phổ biến khi tinh chỉnh mô hình lập luận. Nếu bạn quan tâm cách năng lực lập luận phát triển trong huấn luyện, hãy xem hướng dẫn về tinh chỉnh DeepSeek R1, khám phá các động lực tương tự.
Mô hình được lưu tại checkpoint-400 có khả năng khái quát tốt nhất, với training loss 0,68, validation loss 0,73 và khoảng cách chỉ 0,05. Dù training loss cao hơn checkpoint cuối, nó xử lý câu hỏi mới tốt hơn. Training loss thấp nhất hiếm khi tạo ra mô hình tốt nhất, đó là lý do các chỉ số đánh giá quan trọng.
Chúng ta sẽ kiểm chứng điều này sau bằng cách so sánh mô hình tại checkpoint-400 với mô hình nền bằng một LLM đánh giá. Giờ hãy đi qua từng bước xây dựng quy trình tinh chỉnh này.
Bước 1: Cài đặt Tinker và thiết lập môi trường
Lưu ý: Các bước sau phân rã một script dài khoảng 300 dòng. Vì phần giải thích được đan xen vào các khối mã, chúng tôi khuyến nghị bạn mở script đầy đủ trong tab mới khi làm theo để có bức tranh tổng thể.
Bạn cần Python 3.11 trở lên và kết nối internet ổn định. Vì Tinker xử lý huấn luyện GPU trên máy chủ của họ, kết nối tốt quan trọng hơn một máy tính mạnh.
Bắt đầu bằng cách đăng nhập bảng điều khiển Tinker và tạo khóa API. Lưu khóa này trong tệp .env ở thư mục dự án của bạn:
Khi đã thiết lập xong, bảng điều khiển Tinker trở thành trung tâm để bạn theo dõi các lần chạy huấn luyện và quản lý checkpoint.
Bảng điều khiển Tinker theo dõi mọi lần chạy với các thông tin chính: ID chạy duy nhất, mô hình nền, rank LoRA, và thời điểm yêu cầu gần nhất. Bạn có thể tìm kiếm, lọc và quản lý nhiều thí nghiệm từ giao diện này.
Cài đặt các gói cần thiết. Tinker có các phụ thuộc ngang hàng không tự cài, nên hãy chỉ định rõ:
Các gói transformers và torch cung cấp tokenizer và phép toán tensor mà Tinker dùng nội bộ. Thư viện datasets xử lý tải dữ liệu huấn luyện từ Hugging Face.
Giờ hãy thiết lập import và một hàm hỗ trợ retry. Khi huấn luyện trên máy chủ từ xa, bạn có thể gặp lỗi kết nối tạm thời không nhất thiết có vấn đề thực sự. Job huấn luyện của bạn vẫn chạy tốt trên hạ tầng Tinker. Trình bao retry này xử lý tự động các lỗi thoáng qua đó:
import time
import numpy as np
from dotenv import load_dotenv
from datasets import load_dataset
import tinker
from tinker import types
defwith_retry(future, max_attempts=3, delay=5):"""Simple retry logic for API futures"""for attempt inrange(max_attempts):try:return future.result()except Exception as e:if attempt == max_attempts -1:raise
time.sleep(delay)Được hỗ trợ bởi
Hàm này nhận một đối tượng future (đại diện cho thao tác chưa hoàn tất) từ API của Tinker và cố lấy kết quả tối đa ba lần, chờ năm giây giữa mỗi lần thử. Hầu hết lỗi tạm thời sẽ tự hết trong khoảng này.
Bước 2: Khởi tạo ServiceClient và tải bộ dữ liệu
ServiceClient là điểm vào Tinker của bạn. Nó tìm các mô hình sẵn có và xử lý xác thực:
load_dotenv()
service_client = tinker.ServiceClient()Được hỗ trợ bởi
Bạn sẽ không dùng nó nhiều sau thiết lập ban đầu. Nó chủ yếu để tạo các client huấn luyện và lấy mẫu cho mô hình cụ thể.
Giờ là lúc tải bộ dữ liệu FinCoT. Nó chứa các câu hỏi tài chính đi kèm chuỗi lập luận từng bước và câu trả lời cuối cùng. Khác với các bộ hỏi đáp đơn giản, FinCoT dạy mô hình “trình bày cách làm” trước khi trả lời, một kỹ năng quan trọng cho ứng dụng cố vấn tài chính nơi người dùng cần hiểu lập luận đằng sau khuyến nghị.
Bộ dữ liệu gồm một phần SFT (tinh chỉnh có giám sát) với chuỗi lập luận đầy đủ và một phần RL cho học tăng cường. Hãy dùng phần SFT cho huấn luyện và lấy mẫu từ phần RL cho đánh giá để đảm bảo mô hình khái quát hóa với ví dụ khác biệt.
train_data_raw = dataset["SFT"]# 7,686 examples with reasoning chains
val_data_raw = dataset["RL"].shuffle(seed=42).select(range(500))# 500 validation examplesprint(f"Loaded {len(train_data_raw)} training examples")print(f"Loaded {len(val_data_raw)} validation examples")Được hỗ trợ bởi
Bước 3: Tạo client huấn luyện LoRA của bạn
Giờ hãy tạo một client huấn luyện LoRA cho Qwen3-8B:
training_client = service_client.create_lora_training_client(
base_model="Qwen/Qwen3-8B",
rank=32)Được hỗ trợ bởi
Cùng bóc tách những gì đang xảy ra:
Qwen/Qwen3-8B: Đây là một mô hình 8 tỷ tham số, đủ mạnh cho các tác vụ thực tế nhưng vẫn hiệu quả để huấn luyện. Điểm cân bằng tốt để học. Bạn có thể xem toàn bộ mô hình sẵn có trong danh mục mô hình của Tinker.
LoRA (Low-Rank Adaptation): Thay vì cập nhật cả 8 tỷ tham số, LoRA huấn luyện các lớp “adapter” nhỏ điều chỉnh hành vi mô hình nền. Hãy hình dung như thêm kính lọc tùy biến cho một chiếc máy ảnh thay vì xây lại cả máy. Mô hình nền vẫn đóng băng trên máy chủ Tinker; bạn chỉ huấn luyện các adapter nhỏ này.
rank=32: Tham số này điều khiển số tham số có thể học trong adapter LoRA. Rank 32 hoạt động tốt cho bộ dữ liệu 5.000-10.000 mẫu. Bộ lớn hơn có thể cần rank=64 hoặc 128 để có sức chứa thích nghi cao hơn.
Mô hình ngôn ngữ không làm việc trực tiếp với từ. Chúng làm việc với “token”, đại diện cho các mảnh văn bản. Một tokenizer chia nhỏ văn bản thành các mảnh này. Ví dụ, “financial” có thể là một token, trong khi “understanding” có thể tách thành “under” và “standing”.
Tokenizer chuyển văn bản thành số (ID token) để mô hình xử lý. Khi lấy tokenizer từ client huấn luyện, bạn đảm bảo dùng đúng tokenization mà Qwen3-8B kỳ vọng.
Bước 4: Chuyển đổi dữ liệu sang định dạng của Tinker
Tinker cần dữ liệu huấn luyện của bạn theo định dạng types.Datum. Định dạng này tách đầu vào mô hình khỏi cấu hình hàm mất mát, cho bạn quyền kiểm soát chính xác token nào đóng góp vào huấn luyện.
Khi tinh chỉnh mô hình ngôn ngữ, bạn thường muốn mô hình học cách tạo câu trả lời tốt, không phải ghi nhớ câu hỏi. Bạn làm điều này bằng cách gán trọng số khác nhau cho các phần khác nhau của đầu vào:
Các token gợi ý (câu hỏi): Trọng số = 0,0 (không học từ phần này)
Các token hoàn thành (câu trả lời): Trọng số = 1,0 (học từ phần này)
Hãy xây hàm chuyển đổi dữ liệu từng bước. Bắt đầu với chữ ký hàm:
Các mô hình khác nhau kỳ vọng định dạng khác nhau cho hội thoại nhiều lượt. Qwen3 dùng các token đặc biệt như <|im_start|> và <|im_end|> để đánh dấu ranh giới thông điệp. Chia mỗi thông điệp thành phần “quan sát” (tiêu đề vai trò) và phần “hành động” (nội dung thực):
# Qwen3 chat format - split into observation and action parts
user_ob ="<|im_start|>user\n"
user_ac =f"{example['Question']}<|im_end|>"
assistant_ob ="\n<|im_start|>assistant\n"# Include both reasoning process AND final answer
assistant_ac =f"{example['Reasoning_process']}\n\nFinal Answer: {example['Final_response']}<|im_end|>"Được hỗ trợ bởi
Bộ FinCoT cung cấp lập luận có cấu trúc, nên chúng ta nối các trường Reasoning_process và Final_response. Điều này dạy mô hình trình bày cách làm trước khi trả lời.
Token hóa từng phần riêng biệt
Để theo dõi nơi áp dụng trọng số, mỗi phần thông điệp cần được token hóa riêng.
# Tokenize each part separately to track weight boundaries
user_ob_tokens = tokenizer.encode(user_ob, add_special_tokens=False)
user_ac_tokens = tokenizer.encode(user_ac, add_special_tokens=False)
assistant_ob_tokens = tokenizer.encode(assistant_ob, add_special_tokens=False)
assistant_ac_tokens = tokenizer.encode(assistant_ac, add_special_tokens=False)# Combine all tokens
all_tokens = user_ob_tokens + user_ac_tokens + assistant_ob_tokens + assistant_ac_tokensĐược hỗ trợ bởi
Lọc các chuỗi quá dài
Một số ví dụ FinCoT có chuỗi lập luận cực kỳ chi tiết vượt quá ngưỡng ngữ cảnh thoải mái của Qwen3-8B. Dù mô hình về mặt kỹ thuật hỗ trợ 32.768 token, chuỗi rất dài có thể gây bất ổn trong huấn luyện:
# Check if sequence exceeds max lengthiflen(all_tokens)> max_length:returnNone# Skip this exampleĐược hỗ trợ bởi
Lọc các ví dụ trên 10.000 token chỉ loại 5-6% dữ liệu, đồng thời cải thiện đáng kể độ ổn định huấn luyện.
Gán trọng số để kiểm soát mô hình học từ đâu
Đặt trọng số 0,0 cho câu hỏi (để mô hình không học dự đoán câu hỏi) và 1,0 cho câu trả lời (để mô hình học tạo phản hồi tốt):
# Weights: only train on assistant's answer (action part)
weights = np.array([0.0]*len(user_ob_tokens)+[0.0]*len(user_ac_tokens)+[0.0]*len(assistant_ob_tokens)+[1.0]*len(assistant_ac_tokens))Được hỗ trợ bởi
Dịch chuyển token và trọng số cho bài toán dự đoán token kế tiếp
Mô hình ngôn ngữ dự đoán token kế tiếp trong chuỗi. Khi mô hình thấy các token 0-9, nó sẽ dự đoán token 10. Vì vậy mục tiêu của bạn luôn là đầu vào được dịch chuyển lên một vị trí:
# CRITICAL: Shift tokens AND weights for next-token prediction
input_tokens_model = all_tokens[:-1]
target_tokens = all_tokens[1:]
weights_shifted = weights[1:]Được hỗ trợ bởi
Lưu ý quan trọng là bạn phải dịch chuyển cả trọng số cùng với token. Nếu không, phép tính loss sẽ lệch: mô hình sẽ được huấn luyện để dự đoán token trả lời đầu tiên, nhưng trọng số tại vị trí đó vẫn là 0,0 từ phần gợi ý. Lỗi căn chỉnh này có thể khiến mô hình học không đúng.
Trả về dữ liệu đã định dạng
Cuối cùng, hàm prepare_datum() trả về dữ liệu đã định dạng, sẵn sàng xử lý.
return types.Datum(
model_input=types.ModelInput.from_ints(tokens=input_tokens_model),
loss_fn_inputs=dict(weights=weights_shifted, target_tokens=target_tokens),)Được hỗ trợ bởi
Bằng cách áp dụng hàm đã định nghĩa cho các phần huấn luyện và đánh giá thô, giờ chúng ta có thể xử lý toàn bộ bộ dữ liệu:
# Process and filter training data
training_data_raw =[prepare_datum(example)for example in train_data_raw]
training_data =[d for d in training_data_raw if d isnotNone]
skipped =len(train_data_raw)-len(training_data)print(f"Processed {len(training_data)} examples (skipped {skipped} too-long sequences)")# Output: Processed 7,244 examples (skipped 442 too-long sequences)# Process validation data
val_data_raw_processed =[prepare_datum(example)for example in val_data_raw]
val_data =[d for d in val_data_raw_processed if d isnotNone]print(f"Validation set: {len(val_data)} examples")Được hỗ trợ bởi
Bước 5: Huấn luyện mô hình với vòng lặp huấn luyện
Vòng lặp huấn luyện dùng hai nguyên thủy API cốt lõi của Tinker: forward_backward và optim_step. Hãy xây nó từng bước với theo dõi đánh giá để phát hiện overfit sớm.
Định nghĩa hàm validation loss
Trước tiên, định nghĩa hàm tính validation loss. Khác với training loss, validation loss cho biết mô hình khái quát tốt thế nào với dữ liệu chưa thấy. Điều này rất quan trọng để phát hiện overfit.
defcompute_validation_loss(val_data, batch_size=100):"""Compute loss on validation set (forward only, no backward)"""
batch_indices = np.random.choice(len(val_data), size=min(batch_size,len(val_data)), replace=False)
batch =[val_data[i]for i in batch_indices]# Forward pass only (no backward!)
fwd_future = training_client.forward(batch, loss_fn="cross_entropy")
fwd_result = with_retry(fwd_future)# Calculate per-token loss
loss_sum = fwd_result.metrics["loss:sum"]
total_completion_tokens =sum(
np.sum(np.array(val_data[i].loss_fn_inputs["weights"].data)>0)for i in batch_indices
)return loss_sum / total_completion_tokens if total_completion_tokens >0else0Được hỗ trợ bởi
Phương thức forward() tính loss mà không tính gradient, giúp đánh giá hiệu quả vì bạn chỉ cần đo lường hiệu năng chứ không cập nhật trọng số. Tính validation loss thêm chi phí tối thiểu (chỉ forward, không tính gradient) nhưng cung cấp cảnh báo sớm khi khoảng cách giữa training và validation loss vượt 0,2, báo hiệu mô hình đang ghi nhớ thay vì học.
Cấu hình tham số huấn luyện
Chúng ta cần xác định số epoch cũng như learning rate. LoRA cần learning rate cao hơn đáng kể so với tinh chỉnh toàn phần, thường lớn hơn 10-20 lần.
# Training configuration
n_samples =len(training_data)# 7,244
n_epochs =4# More epochs for smaller dataset
batch_size =32# Calculate optimal LR for Qwen3-8B with LoRA# Formula: base_lr * lora_multiplier * (2000 / hidden_size) ** exponent# For Qwen: base=5e-5, multiplier=10, hidden_size=4096, exponent=0.0775
learning_rate =5e-5*10.0*(2000/4096)**0.0775# ≈ 4.7e-4Được hỗ trợ bởi
Công thức tính đến kích thước mô hình (Qwen3-8B có hidden size 4.096) và dùng số mũ xác định theo thực nghiệm khác nhau theo họ mô hình, như được ghi trong Tinker cookbook. Với Qwen, số mũ là 0,0775, còn Llama dùng 0,781. Trường hợp của chúng ta cho ra learning rate khoảng 4,7e-4, hội tụ ổn định mà không nổ gradient.
Thiết lập warmup cho learning rate
Bắt đầu ngay với learning rate đầy đủ có thể gây nổ gradient sớm khi mô hình chưa thích nghi với tác vụ. Warmup tăng dần learning rate từ gần 0 đến giá trị mục tiêu trong 200 vòng lặp đầu. Bạn có thể thấy rõ trong hình trực quan huấn luyện trước đó, đường learning rate (xanh lá) tăng mượt trong 200 vòng lặp đầu.
Logic warmup tăng dần learning rate trong 200 vòng lặp đầu, ngăn bất ổn sớm.
Gọi các nguyên thủy huấn luyện cốt lõi của Tinker
Ở mỗi vòng lặp, các nguyên thủy cốt lõi của Tinker được gọi như sau:
# API Primitive 1: forward_backward - compute gradients
fwdbwd_future = training_client.forward_backward(batch, loss_fn="cross_entropy")# API Primitive 2: optim_step - update parameters
optim_future = training_client.optim_step(types.AdamParams(learning_rate=current_lr))# Wait for results with retry logic
fwdbwd_result = with_retry(fwdbwd_future)
optim_result = with_retry(optim_future)Được hỗ trợ bởi
forward_backward tính gradient bằng cách xác định mô hình sai lệch thế nào và nên điều chỉnh mỗi tham số theo hướng nào. Nó dùng cross-entropy loss, đo lường mức độ phân phối xác suất dự đoán của mô hình khớp với token kế tiếp thực tế. optim_step thực sự cập nhật tham số mô hình dựa trên các gradient đó bằng trình tối ưu Adam.
Lưu ý cả hai phương thức trả về đối tượng “future” ngay lập tức. Điều này cho phép Tinker xử lý nhiều thao tác đồng thời, giúp tăng tốc. Gọi with_retry(future) sẽ chờ thao tác cụ thể đó hoàn tất.
Theo dõi và hiển thị chỉ số loss
Chúng ta tính cả tổng loss và loss theo token, rồi thêm vào các danh sách tương ứng:
# Track loss
loss_sum = fwdbwd_result.metrics["loss:sum"]
total_completion_tokens =sum(
np.sum(np.array(training_data[i].loss_fn_inputs["weights"].data)>0)for i in batch_indices
)
per_token_loss = loss_sum / total_completion_tokens
losses.append(loss_sum)
per_token_losses.append(per_token_loss)if iteration %10==0:
warmup_indicator ="🔥"if iteration < warmup_steps else""print(f"{warmup_indicator} Iteration {iteration} | Train: {per_token_loss:.4f} | LR: {current_lr:.6f}")Được hỗ trợ bởi
Per-token loss chuẩn hóa loss theo số token câu trả lời, giúp dễ diễn giải hơn giữa các batch size khác nhau. Một lượt huấn luyện tốt thường bắt đầu với per-token loss quanh 1,2-1,5 và giảm xuống dưới 0,8 vào checkpoint-400. Nếu loss của bạn bắt đầu trên 2,0 hoặc không giảm sau 50 vòng lặp, hãy kiểm tra chuẩn bị dữ liệu và learning rate.
Thêm kiểm tra đánh giá định kỳ và checkpoint
Lưu trọng số mỗi 200 vòng lặp tạo các snapshot để so sánh. Như bạn thấy trong kết quả trước đó, checkpoint-400 khái quát tốt hơn checkpoint cuối dù training loss cao hơn. Luôn lưu nhiều checkpoint và đánh giá chúng trên dữ liệu để dành. Các checkpoint vẫn tồn tại trên máy chủ Tinker sau khi script kết thúc.
Tinker tổ chức checkpoint thành hai loại: checkpoint trạng thái đầy đủ (để tiếp tục huấn luyện khi bị gián đoạn) và trọng số cho sampler (checkpoint gọn nhẹ để suy luận). Lưu ý checkpoint-400 xuất hiện ở cả hai định dạng, giúp vừa tiếp tục huấn luyện vừa triển khai mô hình dễ dàng.
Nếu lượt huấn luyện của bạn bị gián đoạn, bạn có thể tiếp tục từ bất kỳ checkpoint đã lưu nào bằng trọng số trạng thái đầy đủ, cho phép tiếp tục huấn luyện mà không phải bắt đầu lại.
Sau khi huấn luyện hoàn tất, lưu trọng số mô hình cuối:
sampling_client = training_client.save_weights_and_get_sampling_client(
name="financial-qa-qwen3-8b-lora")Được hỗ trợ bởi
Trọng số được lưu trên máy chủ của Tinker, không phải máy bạn. Các adapter LoRA thường chỉ cần vài chục megabyte. Tinker có thể tùy chọn xuất chúng để dùng với nhà cung cấp suy luận bên ngoài nếu bạn muốn triển khai mô hình ngoài hạ tầng của họ.
Bước 7: Kiểm thử mô hình với câu hỏi mẫu
Cuối cùng, kiểm thử mô hình đã tinh chỉnh bằng nguyên thủy API sample. Trước tiên, cấu hình tham số lấy mẫu:
sampling_params = types.SamplingParams(
max_tokens=200,
temperature=0.7,
top_p=0.9,
stop_sequences=["<|im_end|>"])Được hỗ trợ bởi
Giải thích các tham số này:
max_tokens: Độ dài tối đa của phản hồi sinh ra (200 token xấp xỉ 150 từ).
temperature: Điều khiển tính ngẫu nhiên khi sinh. Giá trị thấp (0,1-0,5) khiến đầu ra tập trung và tất định hơn; giá trị cao (0,7-1,0) cho phép sáng tạo hơn. 0,7 cân bằng tính mạch lạc và đa dạng.
top_p (nucleus sampling): Chỉ xét tập nhỏ nhất các token có xác suất cộng dồn vượt ngưỡng này. 0,9 nghĩa là “chỉ xét các token chiếm tổng 90% khối xác suất”. Điều này ngăn mô hình chọn token rất khó xảy ra.
stop_sequences: Bảo mô hình dừng sinh khi gặp chuỗi này. <|im_end|> là ký hiệu kết thúc chuỗi.
Sinh phản hồi cho các câu hỏi kiểm thử:
questions =["What are the main risks associated with investing in stocks?","How does diversification help reduce portfolio risk?"]for question in questions:
model_input = types.ModelInput.from_ints(tokenizer.encode(question))
response = with_retry(
sampling_client.sample(
prompt=model_input,
num_samples=1,
sampling_params=sampling_params
))
answer = tokenizer.decode(response.sequences[0].tokens)print(f"Q: {question}")print(f"A: {answer}\n")Được hỗ trợ bởi
Dưới đây là hai đầu ra ví dụ từ mô hình đã tinh chỉnh (đã rút gọn để minh họa):
Q: What are the main risks associated with investing in stocks?
A: Investing in stocks carries several key risks. Market risk represents the potential for stock prices to decline due to economic downturns or market volatility. Company-specific risk arises from poor management decisions, competitive pressures, or operational failures that affect individual stocks. Liquidity risk occurs when you cannot sell shares quickly without significantly impacting the price. Additionally, investors face inflation risk, where returns may not keep pace with rising prices...
Q: How does diversification help reduce portfolio risk?
A: Diversification reduces portfolio risk by spreading investments across different asset classes, sectors, and geographic regions. When you hold multiple uncorrelated assets, losses in one investment can be offset by gains in others. For example, if technology stocks decline but healthcare stocks rise, a diversified portfolio experiences less volatility than one concentrated in technology alone. The key principle is that different assets respond differently to market conditions...Được hỗ trợ bởi
Đối tượng phản hồi chứa danh sách sequences vì bạn có thể yêu cầu nhiều mẫu mỗi prompt. Truy cập token qua sequences[0].tokens và giải mã lại thành văn bản bằng cùng tokenizer.
Bạn đã trình diễn thành công cả bốn nguyên thủy API cốt lõi:
forward_backward: Tính gradient từ dữ liệu huấn luyện
optim_step: Cập nhật tham số mô hình với trình tối ưu Adam
save_weights_and_get_sampling_client: Lưu trữ mô hình đã tinh chỉnh
sample: Tạo dự đoán từ mô hình đã tinh chỉnh
Cùng một mẫu quy trình này có thể mở rộng sang các mô hình huấn luyện nâng cao hơn. Với học tăng cường hoặc tối ưu hóa theo sở thích, bạn sẽ dùng các nguyên thủy giống nhau nhưng với hàm mất mát và định dạng dữ liệu khác. Nếu bạn quan tâm căn chỉnh mô hình theo sở thích con người, hãy xem các kỹ thuật tinh chỉnh theo sở thích, xây dựng trên cùng nền tảng. Tinker cookbook cung cấp ví dụ cho các kịch bản nâng cao này.
Nhưng làm sao biết tinh chỉnh thực sự cải thiện hiệu năng? Thay vì dựa vào ấn tượng chủ quan, bạn cần đánh giá nghiêm ngặt. Ở phần tiếp theo, bạn sẽ thấy kết quả từ đánh giá LLM-đóng-vai-trọng-tài so sánh mô hình đã tinh chỉnh với Qwen3-8B gốc trên 10 câu hỏi tài chính đa dạng.
Đánh giá mô hình đã tinh chỉnh với LLM trọng tài
Để đo lường khách quan, chúng tôi dùng LLM-đóng-vai-trọng-tài: GPT-4o đánh giá checkpoint-400 so với Qwen3-8B gốc trên 10 câu hỏi tài chính đa dạng, chấm điểm từng phản hồi về độ chính xác, rõ ràng, đầy đủ và thuật ngữ tài chính.
Mô hình đã tinh chỉnh đạt 8,5/10, so với 6,5 của mô hình gốc, thắng cả 10 phép so. Kết luận tiết lộ lý do: nó đưa ra giải thích đầy đủ với lập luận có cấu trúc, tự tin, trong khi mô hình gốc lưỡng lự với “tôi nghĩ” và “có lẽ”, để dở dang ý.
Điều này xác nhận hiệu năng thực tế tốt hơn của checkpoint-400. Training loss thấp hơn ở vòng lặp 900 sẽ chỉ cho ta ghi nhớ, không phải lập luận.
Bạn đã thấy cách Tinker đơn giản hóa tinh chỉnh mà không đánh đổi quyền kiểm soát. Bốn nguyên thủy API cốt lõi, forward_backward, optim_step, save_weights_and_get_sampling_client, và sample, cung cấp các khối xây dựng cho quy trình huấn luyện tùy chỉnh trong khi Tinker xử lý hạ tầng phân tán.
Mô hình H&Đ tài chính chúng ta xây dựng thể hiện các thực hành tốt cho sản xuất: theo dõi đánh giá giúp phát hiện overfit sớm, checkpoint-400 vượt mô hình cuối nhờ tập trung vào khái quát hóa, và đánh giá LLM-đóng-vai-trọng-tài xác nhận cải thiện 2 điểm so với mô hình gốc. Các mẫu hình này áp dụng dù bạn tinh chỉnh mô hình 8B hay 70B tham số.
Nền tảng đang ở giai đoạn beta với quyền truy cập theo danh sách chờ, nhưng các khái niệm bạn đã học chuyển giao trực tiếp khi có quyền. Các lượt huấn luyện tôi thực hiện cho hướng dẫn này (kể cả những lượt thất bại và thử nghiệm) tiêu tốn 150 tín dụng khởi đầu, vì vậy với tín dụng ban đầu, bạn có thể chạy hướng dẫn này 6 lần và thêm các thí nghiệm khác, đủ dư dả để học và lặp trên các dự án tinh chỉnh của riêng bạn.
Tiếp theo là gì? Hãy thử tinh chỉnh trên dữ liệu theo miền của bạn, thử nghiệm các rank LoRA và learning rate khác nhau, hoặc khám phá các mô hình huấn luyện nâng cao như học tăng cường từ phản hồi con người. Tinker cookbook có ví dụ cho các kịch bản này. Hãy bắt đầu nghĩ về trường hợp sử dụng của bạn ngay bây giờ—bạn muốn mô hình của mình học hành vi gì?
Tôi là người sáng tạo nội dung về khoa học dữ liệu với hơn 2 năm kinh nghiệm và là một trong những tài khoản có lượng người theo dõi lớn nhất trên Medium. Tôi thích viết các bài chuyên sâu về AI và ML với chút giọng điệu mỉa mai, vì bạn cũng phải làm gì đó để chúng bớt khô khan. Tôi đã xuất bản hơn 130 bài viết và một khóa học trên DataCamp, cùng với một khóa nữa đang được thực hiện. Nội dung của tôi đã được hơn 5 triệu lượt xem, trong đó 20 nghìn người đã trở thành người theo dõi trên cả Medium và LinkedIn.
Học cách tích hợp trí tuệ nhân tạo (AI) vào các ứng dụng phần mềm thông qua việc sử dụng các giao diện lập trình ứng dụng (API) và các thư viện mã nguồn mở. Hãy bắt đầu hành trình trở thành Kỹ sư Trí tuệ Nhân tạo ngay hôm nay!
Học cách phát triển các ứng dụng được hỗ trợ bởi trí tuệ nhân tạo (AI) bằng cách sử dụng các công cụ phát triển AI mới nhất, bao gồm API OpenAI, Hugging Face và LangChain.
Tinh chỉnh các mô hình ngôn ngữ lớn thường đồng nghĩa với việc phải xử lý hạ tầng GPU phân tán, quản lý lỗi cụm và gỡ lỗi các script huấn luyện phức tạp. Tinker ra đời để giải quyết những điều đó.
Được Thinking Machines Lab của Mira Murati phát hành ngày 1 tháng 10, 2025, Tinker là một API huấn luyện xử lý toàn bộ phần phức tạp về hạ tầng trong khi vẫn trao cho bạn toàn quyền kiểm soát thuật toán và dữ liệu. Bạn chỉ cần viết các script Python đơn giản với bốn hàm cốt lõi, và Tinker sẽ chạy chúng trên GPU phân tán cho nhiều mô hình mã nguồn mở như Llama 70B hoặc Qwen 235B.
Nền tảng sử dụng tinh chỉnh Low-Rank Adaptation (LoRA) để giảm chi phí và hỗ trợ mọi thứ từ học có giám sát đến học tăng cường. Các nhóm nghiên cứu tại Princeton, Stanford và Berkeley đã sử dụng cho công việc của họ.
Trong hướng dẫn này, tôi sẽ đưa bạn qua các bước cài đặt Tinker, hiểu API của nó, và tinh chỉnh một mô hình Hỏi & Đáp tài chính hoàn chỉnh bằng mô hình nền Qwen3-8B. Nếu bạn muốn tìm hiểu thêm về tinh chỉnh với bài thực hành, tôi khuyến nghị xem khóa học về Tinh chỉnh với Llama 3.
Tinker là gì?
Thinking Machines Lab xây dựng Tinker cho những ai muốn tùy biến cách mô hình học mà không cần trở thành chuyên gia hạ tầng.
Ai đang dùng Tinker?
Nền tảng hướng tới ba nhóm:
Mỗi nhóm đều có nhu cầu chung: họ biết mô hình cần làm gì, nhưng các giao diện tinh chỉnh tiêu chuẩn không cho họ đủ quyền kiểm soát.
Ví dụ, các nhóm học thuật có thể dùng để thử nghiệm thuật toán mới. Một phòng thí nghiệm hóa học có thể muốn huấn luyện mô hình theo các mẫu lập luận theo miền không phù hợp với các khuôn mẫu instruction-tuning điển hình. Một startup xây dựng bot cố vấn tài chính có thể dùng mô hình để tuân thủ các định dạng đầu ra và chuỗi lập luận cụ thể.
Điểm chung của các trường hợp này là họ cần sửa đổi chính quá trình huấn luyện, không chỉ thay bộ dữ liệu.
Điều gì khiến Tinker khác biệt?
Đa số nền tảng tối ưu cho một trong hai thứ: dễ dùng hoặc linh hoạt. Cách tiếp cận của Tinker là hai điều này không nhất thiết xung đột. Nền tảng cho bạn truy cập cấp thấp vào huấn luyện qua bốn thao tác cốt lõi, nhưng tự động xử lý mọi thứ còn lại:
Tinker cung cấp các khả năng này qua bốn nguyên thủy API mà bạn sẽ học trong phần thực hành.
Điều này hiệu quả vì phần lớn độ phức tạp huấn luyện đến từ hạ tầng, không phải bản thân thuật toán. Chạy một vòng lặp huấn luyện tùy chỉnh trên laptop khá đơn giản. Chạy nó trên 100 GPU với khả năng phục hồi lỗi và điều phối tài nguyên thì khó. Tinker xử lý phần thứ hai để bạn tập trung vào phần đầu.
Vị trí của Tinker trong hệ sinh thái
Hệ sinh thái công cụ AI có thể chia đại khái thành ba lớp: nhà cung cấp điện toán đám mây cung cấp GPU thô, nền tảng quản lý chạy các quy trình dựng sẵn, và framework giúp bạn xây hệ thống huấn luyện từ đầu. Tinker nằm giữa nền tảng quản lý và framework. Bạn có nhiều quyền kiểm soát hơn so với các nền tảng như Hugging Face AutoTrain, nhưng ít việc hạ tầng hơn so với tự dựng cụm trên Google Cloud Platform (GCP).
Giá Tinker và tín dụng
Tinker dùng biểu giá minh bạch theo token, biến thiên theo kích thước mô hình và loại thao tác. Huấn luyện Qwen3-8B tốn $0,40 cho mỗi triệu token. Tin vui: người dùng mới nhận $150 tín dụng sau khi được duyệt khỏi danh sách chờ, dư sức cho vài lần huấn luyện thử nghiệm như trong hướng dẫn này.
Nguồn: Thinking Machines Lab
Ví dụ với Tinker: Tinh chỉnh Qwen3-8B cho Hỏi & Đáp tài chính
Trong phần này, tôi sẽ hướng dẫn bạn xây dựng một quy trình tinh chỉnh hoàn chỉnh bằng API của Tinker. Chúng ta sẽ tinh chỉnh Qwen3-8B trên dữ liệu hỏi đáp tài chính bằng LoRA, học cả bốn nguyên thủy API cốt lõi đồng thời quan sát thực hành tốt trong môi trường sản xuất.
Để có cái nhìn chi tiết hơn về mô hình, hãy xem bài viết về Qwen3.
Lưu ý quan trọng: Tinker hiện đang ở giai đoạn beta với quyền truy cập theo danh sách chờ. Nếu bạn đã có quyền, bạn có thể làm theo và chạy mã. Nếu bạn đang trong danh sách chờ, bạn vẫn có thể đọc để hiểu quá trình tinh chỉnh với Tinker đơn giản ra sao. Khi có quyền, bạn sẽ sẵn sàng bắt tay ngay.
Kết quả huấn luyện và chọn checkpoint
Hãy xem kết quả huấn luyện trước. Hiểu chuyện gì đã xảy ra sẽ giúp bạn nhận ra các mẫu này khi chạy job tinh chỉnh của riêng mình.
Chúng tôi tinh chỉnh Qwen3-8B trên bộ dữ liệu FinCoT, một bộ dữ liệu lập luận tài chính theo chuỗi suy nghĩ, bằng LoRA với rank 32. Sau khi lọc các chuỗi không dài quá 10.000 token, chúng tôi còn 7.244 mẫu huấn luyện và 500 mẫu để đánh giá.
Huấn luyện chạy 904 vòng lặp qua bốn epoch, mất khoảng ba giờ để hoàn tất, trong khi Tinker xử lý toàn bộ điều phối GPU phân tán.
Một epoch là một lượt duyệt toàn bộ dữ liệu huấn luyện. Vì có 226 batch mỗi epoch (7.244 mẫu chia cho batch size 32), bốn epoch tổng cộng 904 vòng lặp.
Phân tích kết quả huấn luyện
Biểu đồ sau theo dõi ba chỉ số: training loss (xanh), validation loss (đỏ), và learning rate (xanh lá).
Giai đoạn đầu (vòng lặp 0-400) trông ổn: cả training và validation loss cùng giảm mạnh, từ trên 1,4 xuống dưới 0,8 và duy trì cách nhau khoảng 0,1.
Giai đoạn này cho thấy mô hình đang học hiệu quả các mẫu có khả năng khái quát trong dữ liệu. Learning rate (đường xanh lá) tăng dần mượt trong 200 vòng lặp đầu, khi warmup ổn định huấn luyện.
Khoảng vòng lặp 400-600, tình hình thay đổi. Training loss tiếp tục giảm, nhưng validation loss chững quanh 0,75-0,8, nới rộng khoảng cách tới 0,13 khi mô hình bắt đầu overfit. Từ 600-900, sự phân kỳ trở nên rõ ràng: training loss giảm mạnh xuống 0,39 trong khi validation loss tăng lên 0,8, cho thấy mô hình đã chuyển từ học mẫu lập luận sang ghi nhớ ví dụ.
Mẫu hình này khá phổ biến khi tinh chỉnh mô hình lập luận. Nếu bạn quan tâm cách năng lực lập luận phát triển trong huấn luyện, hãy xem hướng dẫn về tinh chỉnh DeepSeek R1, khám phá các động lực tương tự.
Mô hình được lưu tại checkpoint-400 có khả năng khái quát tốt nhất, với training loss 0,68, validation loss 0,73 và khoảng cách chỉ 0,05. Dù training loss cao hơn checkpoint cuối, nó xử lý câu hỏi mới tốt hơn. Training loss thấp nhất hiếm khi tạo ra mô hình tốt nhất, đó là lý do các chỉ số đánh giá quan trọng.
Chúng ta sẽ kiểm chứng điều này sau bằng cách so sánh mô hình tại checkpoint-400 với mô hình nền bằng một LLM đánh giá. Giờ hãy đi qua từng bước xây dựng quy trình tinh chỉnh này.
Bước 1: Cài đặt Tinker và thiết lập môi trường
Lưu ý: Các bước sau phân rã một script dài khoảng 300 dòng. Vì phần giải thích được đan xen vào các khối mã, chúng tôi khuyến nghị bạn mở script đầy đủ trong tab mới khi làm theo để có bức tranh tổng thể.
Bạn cần Python 3.11 trở lên và kết nối internet ổn định. Vì Tinker xử lý huấn luyện GPU trên máy chủ của họ, kết nối tốt quan trọng hơn một máy tính mạnh.
Bắt đầu bằng cách đăng nhập bảng điều khiển Tinker và tạo khóa API. Lưu khóa này trong tệp
.envở thư mục dự án của bạn:Khi đã thiết lập xong, bảng điều khiển Tinker trở thành trung tâm để bạn theo dõi các lần chạy huấn luyện và quản lý checkpoint.
Bảng điều khiển Tinker theo dõi mọi lần chạy với các thông tin chính: ID chạy duy nhất, mô hình nền, rank LoRA, và thời điểm yêu cầu gần nhất. Bạn có thể tìm kiếm, lọc và quản lý nhiều thí nghiệm từ giao diện này.
Cài đặt các gói cần thiết. Tinker có các phụ thuộc ngang hàng không tự cài, nên hãy chỉ định rõ:
Các gói
transformersvàtorchcung cấp tokenizer và phép toán tensor mà Tinker dùng nội bộ. Thư việndatasetsxử lý tải dữ liệu huấn luyện từ Hugging Face.Giờ hãy thiết lập import và một hàm hỗ trợ retry. Khi huấn luyện trên máy chủ từ xa, bạn có thể gặp lỗi kết nối tạm thời không nhất thiết có vấn đề thực sự. Job huấn luyện của bạn vẫn chạy tốt trên hạ tầng Tinker. Trình bao retry này xử lý tự động các lỗi thoáng qua đó:
Hàm này nhận một đối tượng future (đại diện cho thao tác chưa hoàn tất) từ API của Tinker và cố lấy kết quả tối đa ba lần, chờ năm giây giữa mỗi lần thử. Hầu hết lỗi tạm thời sẽ tự hết trong khoảng này.
Bước 2: Khởi tạo ServiceClient và tải bộ dữ liệu
ServiceClientlà điểm vào Tinker của bạn. Nó tìm các mô hình sẵn có và xử lý xác thực:Bạn sẽ không dùng nó nhiều sau thiết lập ban đầu. Nó chủ yếu để tạo các client huấn luyện và lấy mẫu cho mô hình cụ thể.
Giờ là lúc tải bộ dữ liệu FinCoT. Nó chứa các câu hỏi tài chính đi kèm chuỗi lập luận từng bước và câu trả lời cuối cùng. Khác với các bộ hỏi đáp đơn giản, FinCoT dạy mô hình “trình bày cách làm” trước khi trả lời, một kỹ năng quan trọng cho ứng dụng cố vấn tài chính nơi người dùng cần hiểu lập luận đằng sau khuyến nghị.
Bộ dữ liệu gồm một phần SFT (tinh chỉnh có giám sát) với chuỗi lập luận đầy đủ và một phần RL cho học tăng cường. Hãy dùng phần SFT cho huấn luyện và lấy mẫu từ phần RL cho đánh giá để đảm bảo mô hình khái quát hóa với ví dụ khác biệt.
Bước 3: Tạo client huấn luyện LoRA của bạn
Giờ hãy tạo một client huấn luyện LoRA cho Qwen3-8B:
Cùng bóc tách những gì đang xảy ra:
Để đào sâu cách LoRA hoạt động về mặt toán và cách tinh chỉnh tham số rank, hãy xem tài liệu nhập môn LoRA của Tinker hoặc hướng dẫn toàn diện của DataCamp về làm chủ Low-Rank Adaptation.
Mô hình ngôn ngữ không làm việc trực tiếp với từ. Chúng làm việc với “token”, đại diện cho các mảnh văn bản. Một tokenizer chia nhỏ văn bản thành các mảnh này. Ví dụ, “financial” có thể là một token, trong khi “understanding” có thể tách thành “under” và “standing”.
Tokenizer chuyển văn bản thành số (ID token) để mô hình xử lý. Khi lấy tokenizer từ client huấn luyện, bạn đảm bảo dùng đúng tokenization mà Qwen3-8B kỳ vọng.
Bước 4: Chuyển đổi dữ liệu sang định dạng của Tinker
Tinker cần dữ liệu huấn luyện của bạn theo định dạng
types.Datum. Định dạng này tách đầu vào mô hình khỏi cấu hình hàm mất mát, cho bạn quyền kiểm soát chính xác token nào đóng góp vào huấn luyện.Khi tinh chỉnh mô hình ngôn ngữ, bạn thường muốn mô hình học cách tạo câu trả lời tốt, không phải ghi nhớ câu hỏi. Bạn làm điều này bằng cách gán trọng số khác nhau cho các phần khác nhau của đầu vào:
Hãy xây hàm chuyển đổi dữ liệu từng bước. Bắt đầu với chữ ký hàm:
Định dạng hội thoại theo mẫu chat của Qwen3
Các mô hình khác nhau kỳ vọng định dạng khác nhau cho hội thoại nhiều lượt. Qwen3 dùng các token đặc biệt như
<|im_start|>và<|im_end|>để đánh dấu ranh giới thông điệp. Chia mỗi thông điệp thành phần “quan sát” (tiêu đề vai trò) và phần “hành động” (nội dung thực):Bộ FinCoT cung cấp lập luận có cấu trúc, nên chúng ta nối các trường
Reasoning_processvàFinal_response. Điều này dạy mô hình trình bày cách làm trước khi trả lời.Token hóa từng phần riêng biệt
Để theo dõi nơi áp dụng trọng số, mỗi phần thông điệp cần được token hóa riêng.
Lọc các chuỗi quá dài
Một số ví dụ FinCoT có chuỗi lập luận cực kỳ chi tiết vượt quá ngưỡng ngữ cảnh thoải mái của Qwen3-8B. Dù mô hình về mặt kỹ thuật hỗ trợ 32.768 token, chuỗi rất dài có thể gây bất ổn trong huấn luyện:
Lọc các ví dụ trên 10.000 token chỉ loại 5-6% dữ liệu, đồng thời cải thiện đáng kể độ ổn định huấn luyện.
Gán trọng số để kiểm soát mô hình học từ đâu
Đặt trọng số 0,0 cho câu hỏi (để mô hình không học dự đoán câu hỏi) và 1,0 cho câu trả lời (để mô hình học tạo phản hồi tốt):
Dịch chuyển token và trọng số cho bài toán dự đoán token kế tiếp
Mô hình ngôn ngữ dự đoán token kế tiếp trong chuỗi. Khi mô hình thấy các token 0-9, nó sẽ dự đoán token 10. Vì vậy mục tiêu của bạn luôn là đầu vào được dịch chuyển lên một vị trí:
Lưu ý quan trọng là bạn phải dịch chuyển cả trọng số cùng với token. Nếu không, phép tính loss sẽ lệch: mô hình sẽ được huấn luyện để dự đoán token trả lời đầu tiên, nhưng trọng số tại vị trí đó vẫn là 0,0 từ phần gợi ý. Lỗi căn chỉnh này có thể khiến mô hình học không đúng.
Trả về dữ liệu đã định dạng
Cuối cùng, hàm prepare_datum() trả về dữ liệu đã định dạng, sẵn sàng xử lý.
Bằng cách áp dụng hàm đã định nghĩa cho các phần huấn luyện và đánh giá thô, giờ chúng ta có thể xử lý toàn bộ bộ dữ liệu:
Bước 5: Huấn luyện mô hình với vòng lặp huấn luyện
Vòng lặp huấn luyện dùng hai nguyên thủy API cốt lõi của Tinker:
forward_backwardvàoptim_step. Hãy xây nó từng bước với theo dõi đánh giá để phát hiện overfit sớm.Định nghĩa hàm validation loss
Trước tiên, định nghĩa hàm tính validation loss. Khác với training loss, validation loss cho biết mô hình khái quát tốt thế nào với dữ liệu chưa thấy. Điều này rất quan trọng để phát hiện overfit.
Phương thức
forward()tính loss mà không tính gradient, giúp đánh giá hiệu quả vì bạn chỉ cần đo lường hiệu năng chứ không cập nhật trọng số. Tính validation loss thêm chi phí tối thiểu (chỉ forward, không tính gradient) nhưng cung cấp cảnh báo sớm khi khoảng cách giữa training và validation loss vượt 0,2, báo hiệu mô hình đang ghi nhớ thay vì học.Cấu hình tham số huấn luyện
Chúng ta cần xác định số epoch cũng như learning rate. LoRA cần learning rate cao hơn đáng kể so với tinh chỉnh toàn phần, thường lớn hơn 10-20 lần.
Công thức tính đến kích thước mô hình (Qwen3-8B có hidden size 4.096) và dùng số mũ xác định theo thực nghiệm khác nhau theo họ mô hình, như được ghi trong Tinker cookbook. Với Qwen, số mũ là 0,0775, còn Llama dùng 0,781. Trường hợp của chúng ta cho ra learning rate khoảng 4,7e-4, hội tụ ổn định mà không nổ gradient.
Thiết lập warmup cho learning rate
Bắt đầu ngay với learning rate đầy đủ có thể gây nổ gradient sớm khi mô hình chưa thích nghi với tác vụ. Warmup tăng dần learning rate từ gần 0 đến giá trị mục tiêu trong 200 vòng lặp đầu. Bạn có thể thấy rõ trong hình trực quan huấn luyện trước đó, đường learning rate (xanh lá) tăng mượt trong 200 vòng lặp đầu.
Bắt đầu vòng lặp huấn luyện
Sau khi khởi tạo các danh sách theo dõi loss, chúng ta có thể bắt đầu vòng lặp huấn luyện:
Logic warmup tăng dần learning rate trong 200 vòng lặp đầu, ngăn bất ổn sớm.
Gọi các nguyên thủy huấn luyện cốt lõi của Tinker
Ở mỗi vòng lặp, các nguyên thủy cốt lõi của Tinker được gọi như sau:
forward_backwardtính gradient bằng cách xác định mô hình sai lệch thế nào và nên điều chỉnh mỗi tham số theo hướng nào. Nó dùng cross-entropy loss, đo lường mức độ phân phối xác suất dự đoán của mô hình khớp với token kế tiếp thực tế.optim_stepthực sự cập nhật tham số mô hình dựa trên các gradient đó bằng trình tối ưu Adam.Lưu ý cả hai phương thức trả về đối tượng “future” ngay lập tức. Điều này cho phép Tinker xử lý nhiều thao tác đồng thời, giúp tăng tốc. Gọi
with_retry(future)sẽ chờ thao tác cụ thể đó hoàn tất.Theo dõi và hiển thị chỉ số loss
Chúng ta tính cả tổng loss và loss theo token, rồi thêm vào các danh sách tương ứng:
Per-token loss chuẩn hóa loss theo số token câu trả lời, giúp dễ diễn giải hơn giữa các batch size khác nhau. Một lượt huấn luyện tốt thường bắt đầu với per-token loss quanh 1,2-1,5 và giảm xuống dưới 0,8 vào checkpoint-400. Nếu loss của bạn bắt đầu trên 2,0 hoặc không giảm sau 50 vòng lặp, hãy kiểm tra chuẩn bị dữ liệu và learning rate.
Thêm kiểm tra đánh giá định kỳ và checkpoint
Lưu trọng số mỗi 200 vòng lặp tạo các snapshot để so sánh. Như bạn thấy trong kết quả trước đó, checkpoint-400 khái quát tốt hơn checkpoint cuối dù training loss cao hơn. Luôn lưu nhiều checkpoint và đánh giá chúng trên dữ liệu để dành. Các checkpoint vẫn tồn tại trên máy chủ Tinker sau khi script kết thúc.
Tinker tổ chức checkpoint thành hai loại: checkpoint trạng thái đầy đủ (để tiếp tục huấn luyện khi bị gián đoạn) và trọng số cho sampler (checkpoint gọn nhẹ để suy luận). Lưu ý checkpoint-400 xuất hiện ở cả hai định dạng, giúp vừa tiếp tục huấn luyện vừa triển khai mô hình dễ dàng.
Nếu lượt huấn luyện của bạn bị gián đoạn, bạn có thể tiếp tục từ bất kỳ checkpoint đã lưu nào bằng trọng số trạng thái đầy đủ, cho phép tiếp tục huấn luyện mà không phải bắt đầu lại.
Để xem tài liệu API đầy đủ cho các phương thức này, hãy tham khảo tài liệu huấn luyện và lấy mẫu của Tinker.
Bước 6: Lưu mô hình đã tinh chỉnh
Sau khi huấn luyện hoàn tất, lưu trọng số mô hình cuối:
Trọng số được lưu trên máy chủ của Tinker, không phải máy bạn. Các adapter LoRA thường chỉ cần vài chục megabyte. Tinker có thể tùy chọn xuất chúng để dùng với nhà cung cấp suy luận bên ngoài nếu bạn muốn triển khai mô hình ngoài hạ tầng của họ.
Bước 7: Kiểm thử mô hình với câu hỏi mẫu
Cuối cùng, kiểm thử mô hình đã tinh chỉnh bằng nguyên thủy API
sample. Trước tiên, cấu hình tham số lấy mẫu:Giải thích các tham số này:
max_tokens: Độ dài tối đa của phản hồi sinh ra (200 token xấp xỉ 150 từ).temperature: Điều khiển tính ngẫu nhiên khi sinh. Giá trị thấp (0,1-0,5) khiến đầu ra tập trung và tất định hơn; giá trị cao (0,7-1,0) cho phép sáng tạo hơn. 0,7 cân bằng tính mạch lạc và đa dạng.top_p(nucleus sampling): Chỉ xét tập nhỏ nhất các token có xác suất cộng dồn vượt ngưỡng này. 0,9 nghĩa là “chỉ xét các token chiếm tổng 90% khối xác suất”. Điều này ngăn mô hình chọn token rất khó xảy ra.stop_sequences: Bảo mô hình dừng sinh khi gặp chuỗi này.<|im_end|>là ký hiệu kết thúc chuỗi.Sinh phản hồi cho các câu hỏi kiểm thử:
Dưới đây là hai đầu ra ví dụ từ mô hình đã tinh chỉnh (đã rút gọn để minh họa):
Đối tượng phản hồi chứa danh sách
sequencesvì bạn có thể yêu cầu nhiều mẫu mỗi prompt. Truy cập token quasequences[0].tokensvà giải mã lại thành văn bản bằng cùng tokenizer.Bạn đã trình diễn thành công cả bốn nguyên thủy API cốt lõi:
forward_backward: Tính gradient từ dữ liệu huấn luyệnoptim_step: Cập nhật tham số mô hình với trình tối ưu Adamsave_weights_and_get_sampling_client: Lưu trữ mô hình đã tinh chỉnhsample: Tạo dự đoán từ mô hình đã tinh chỉnhCùng một mẫu quy trình này có thể mở rộng sang các mô hình huấn luyện nâng cao hơn. Với học tăng cường hoặc tối ưu hóa theo sở thích, bạn sẽ dùng các nguyên thủy giống nhau nhưng với hàm mất mát và định dạng dữ liệu khác. Nếu bạn quan tâm căn chỉnh mô hình theo sở thích con người, hãy xem các kỹ thuật tinh chỉnh theo sở thích, xây dựng trên cùng nền tảng. Tinker cookbook cung cấp ví dụ cho các kịch bản nâng cao này.
Nhưng làm sao biết tinh chỉnh thực sự cải thiện hiệu năng? Thay vì dựa vào ấn tượng chủ quan, bạn cần đánh giá nghiêm ngặt. Ở phần tiếp theo, bạn sẽ thấy kết quả từ đánh giá LLM-đóng-vai-trọng-tài so sánh mô hình đã tinh chỉnh với Qwen3-8B gốc trên 10 câu hỏi tài chính đa dạng.
Đánh giá mô hình đã tinh chỉnh với LLM trọng tài
Để đo lường khách quan, chúng tôi dùng LLM-đóng-vai-trọng-tài: GPT-4o đánh giá checkpoint-400 so với Qwen3-8B gốc trên 10 câu hỏi tài chính đa dạng, chấm điểm từng phản hồi về độ chính xác, rõ ràng, đầy đủ và thuật ngữ tài chính.
Mô hình đã tinh chỉnh đạt 8,5/10, so với 6,5 của mô hình gốc, thắng cả 10 phép so. Kết luận tiết lộ lý do: nó đưa ra giải thích đầy đủ với lập luận có cấu trúc, tự tin, trong khi mô hình gốc lưỡng lự với “tôi nghĩ” và “có lẽ”, để dở dang ý.
Điều này xác nhận hiệu năng thực tế tốt hơn của checkpoint-400. Training loss thấp hơn ở vòng lặp 900 sẽ chỉ cho ta ghi nhớ, không phải lập luận.
Xem script so sánh và kết quả chi tiết để chạy đánh giá tương tự trên mô hình của bạn.
Kết luận
Bạn đã thấy cách Tinker đơn giản hóa tinh chỉnh mà không đánh đổi quyền kiểm soát. Bốn nguyên thủy API cốt lõi,
forward_backward,optim_step,save_weights_and_get_sampling_client, vàsample, cung cấp các khối xây dựng cho quy trình huấn luyện tùy chỉnh trong khi Tinker xử lý hạ tầng phân tán.Mô hình H&Đ tài chính chúng ta xây dựng thể hiện các thực hành tốt cho sản xuất: theo dõi đánh giá giúp phát hiện overfit sớm, checkpoint-400 vượt mô hình cuối nhờ tập trung vào khái quát hóa, và đánh giá LLM-đóng-vai-trọng-tài xác nhận cải thiện 2 điểm so với mô hình gốc. Các mẫu hình này áp dụng dù bạn tinh chỉnh mô hình 8B hay 70B tham số.
Nền tảng đang ở giai đoạn beta với quyền truy cập theo danh sách chờ, nhưng các khái niệm bạn đã học chuyển giao trực tiếp khi có quyền. Các lượt huấn luyện tôi thực hiện cho hướng dẫn này (kể cả những lượt thất bại và thử nghiệm) tiêu tốn 150 tín dụng khởi đầu, vì vậy với tín dụng ban đầu, bạn có thể chạy hướng dẫn này 6 lần và thêm các thí nghiệm khác, đủ dư dả để học và lặp trên các dự án tinh chỉnh của riêng bạn.
Tiếp theo là gì? Hãy thử tinh chỉnh trên dữ liệu theo miền của bạn, thử nghiệm các rank LoRA và learning rate khác nhau, hoặc khám phá các mô hình huấn luyện nâng cao như học tăng cường từ phản hồi con người. Tinker cookbook có ví dụ cho các kịch bản này. Hãy bắt đầu nghĩ về trường hợp sử dụng của bạn ngay bây giờ—bạn muốn mô hình của mình học hành vi gì?
Nếu bạn muốn phát triển bộ kỹ năng rộng hơn về huấn luyện và tinh chỉnh các mô hình AI mới nhất cho sản xuất, nhớ xem lộ trình nghề nghiệp Associate AI Engineer for Developers.