GPU cho dự án của bạn · thanh toán crypto không cần KYC Cách thuê
Tiếng Việt
Mở console
Hướng dẫn thực hành / KERNODECK

Notebook của bạn chạy được. Bạn có thể chạy lại mà không cần các cell không?

Để chuyển từ notebook sang script, hãy bắt đầu lại từ một kernel trống, xác định các đầu vào và tách phần tính toán vào các hàm. Sau đó cho chương trình các đối số tường minh và một đích đầu ra riêng. Thành công được kiểm chứng trong một tiến trình mới, với kết quả mong đợi; xuất các cell thành tệp Python không đủ để làm cho trải nghiệm có thể tái lập.

10 phút đọc · Hướng dẫn cho nhà phát triển

1. Tìm lại những gì kernel còn biết

Tệp notebook và trạng thái kernel không phải lúc nào cũng kể cùng một câu chuyện. Một biến có thể đến từ một cell đã xóa, một danh sách có thể đã bị sửa nhiều lần, và một đối tượng được nạp trước lần thay đổi mã cuối cùng có thể vẫn còn trong bộ nhớ. Do đó, kết quả hiển thị không chứng minh rằng các cell hiện tại vẫn tạo ra những kết quả đó theo thứ tự hiển thị.

Hãy giữ một bản sao làm việc, khởi động lại kernel, rồi chạy các cell từ đầu đến cuối. Ghi lại cell đầu tiên bị lỗi hoặc thay đổi kết quả. Hãy tìm phần phụ thuộc còn thiếu thay vì tự tay tiêm lại một biến từ phiên cũ. Kernel Jupyter là một tiến trình riêng biệt; đóng một tab không đồng nghĩa với việc dựng lại một môi trường hoàn toàn mới.

Hãy liệt kê cả các tác động bên ngoài: tải xuống, cài đặt gói, đổi thư mục, đọc một tệp đã được tạo trước đó và sử dụng một biến môi trường. Một cell có kết quả trông như tức thời có thể chỉ đơn giản là đang dùng lại một tệp cũ. Script tương lai của bạn phải có khả năng phân biệt một đầu vào có chủ đích với phần còn sót lại của lần thử nghiệm.

2. Viết hợp đồng trước khi di chuyển mã

Hãy chọn một tác vụ duy nhất để tách ra. Ví dụ: đọc một tệp điểm số, giữ lại các mã định danh có điểm số đạt một ngưỡng và ghi kết quả. Ví dụ trong hướng dẫn này mang tính minh họa, không được thực thi và không dùng GPU. Nó dùng để cho thấy các phụ thuộc của một lần thực thi, chứ không nhằm công bố một phép đo hay một công cụ đi kèm Kernodeck.

Hãy định nghĩa đầu vào, tham số và đầu ra đủ chính xác để kiểm chứng phép biến đổi. Ở đây, ngưỡng mang tính bao gồm: một điểm số bằng 0,5 vẫn được giữ lại. Các mã định danh phải giữ nguyên liên kết với điểm số của chúng và thứ tự đầu vào được bảo toàn. Một đầu ra đã tồn tại không được bị thay thế ngoài ý muốn bởi một lần thử mới.

Bước này tránh một cuộc di chuyển mơ hồ: nếu notebook loại bỏ các điểm số bằng ngưỡng trong khi script giữ chúng lại, nghĩa là bạn đã thay đổi phép tính. Hãy quyết định rõ ràng đây là một sửa lỗi hay một hồi quy. Hãy giữ một trường hợp nằm đúng ngay ranh giới, chứ không chỉ hai giá trị cách xa nhau.

Cuộn bảng để xem tất cả các cột.
Hợp đồng chọn lọc mang tính minh họa, không tuyên bố thực thi.
Thành phầnGiá trị của ví dụTiêu chí
Đầu vàoa: 0,4; b: 0,8; c: 0,5Ba mã định danh riêng biệt, điểm số đã được kiểm chứng trong khoảng từ 0 đến 1.
Tham sốNgưỡng 0,5Phép so sánh lớn hơn hoặc bằng.
Đầu ra mong đợib, rồi cHai mã định danh, không trùng lặp và không sắp xếp lại.

3. Tách ra một hàm không còn phụ thuộc vào một cell

Hãy tách phép biến đổi khỏi các thao tác đọc và ghi. Một hàm tính toán nhận dữ liệu và ngưỡng của nó, rồi trả về các mã định danh được chọn. Hàm này không truy cập một biến toàn cục tên là seuil, không ngầm mở một tệp và không sửa đổi danh sách đầu vào. Điều này cho phép notebook và script gọi đúng cùng một phép tính.

Trong đoạn trích, dữ liệu được giả định đã được kiểm chứng theo hợp đồng trước đó. Do đó hàm này không phải là một bộ kiểm chứng tệp đầy đủ. Giới hạn này là có chủ đích: hãy kiểm tra các định dạng ở đầu vào của chương trình, rồi giữ cho phép biến đổi dễ hiểu. Việc thêm một tham số không nên đòi hỏi phải đi tìm lại cell đã từng thay đổi một giá trị.

Notebook có thể vẫn là công cụ khám phá của bạn. Hãy để nó nhập hàm này thay vì duy trì một bản sao thứ hai. Sau khi sửa đổi mô-đun, hãy bắt đầu lại từ một kernel mới để so sánh hai lộ trình; một hàm cũ đã được nhập trước đó không được làm sai lệch việc kiểm chứng.

Hàm mang tính minh họa — đặt trong mô-đun riêng của bạn, không được thực thi ở đây
def retenir_identifiants(records, seuil):
    return [
        record["id"]
        for record in records
        if record["score"] >= seuil
    ]


if __name__ == "__main__":
    records = [
        {"id": "a", "score": 0.4},
        {"id": "b", "score": 0.8},
        {"id": "c", "score": 0.5},
    ]
    attendu = ["b", "c"]
    obtenu = retenir_identifiants(records, 0.5)
    if obtenu != attendu:
        raise SystemExit("Sélection inattendue")

4. Biến các tham số thành một đầu vào hiển thị

Điểm vào của script xử lý các đối số, kiểm chứng các lựa chọn và gọi các hàm. Mô-đun chuẩn argparse mô tả các tùy chọn và tạo phần trợ giúp; nó không biết các quy tắc nghiệp vụ của bạn. Một số thực được chấp nhận về mặt cú pháp vẫn có thể nằm ngoài khoảng cho phép. Do đó ngưỡng trong ví dụ này cần thêm một bước kiểm tra.

Hãy xác định rõ cách phân giải đường dẫn: tương đối với thư mục mà từ đó lệnh được khởi chạy, hay tương đối với một thư mục dự án được chọn một cách tường minh. Đừng dùng một thao tác đổi thư mục ẩn nào đó ở giữa quá trình tính toán. Khối bên dưới chỉ minh họa phần phân tích đối số; việc đọc dữ liệu và ghi vẫn còn phải gắn vào chương trình của trình đọc.

Hãy giữ các thông tin bí mật nằm ngoài những đối số này. Các tham số có thể chia sẻ mô tả trải nghiệm; quyền truy cập vào một kho lưu trữ hay vùng lưu trữ đi theo một kênh khác. Một lệnh hữu ích cho đồng nghiệp phải có thể được sao chép mà không sao chép luôn một token.

Phân tích đối số mang tính minh họa — đoạn mã chưa được chạy
import argparse
from pathlib import Path


def lire_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input", required=True, type=Path)
    parser.add_argument("--output", required=True, type=Path)
    parser.add_argument("--seuil", required=True, type=float)
    args = parser.parse_args()
    if not 0 <= args.seuil <= 1:
        parser.error("Le seuil doit être compris entre 0 et 1.")
    return args

5. Cho script một điểm kết thúc và các đầu ra có thể kiểm chứng

Hãy đặt phần điều phối trong một hàm main và kích hoạt nó dưới điều kiện if __name__ == "__main__". Nhờ vậy, module có thể được notebook import mà không chạy ngay quá trình xử lý. Các import định nghĩa các công cụ; điểm vào chính quyết định khi nào đọc, tính toán và ghi.

Hãy chỉ định một thư mục riêng cho mỗi lần chạy. Lưu lại các tham số không nhạy cảm thực sự được dùng và danh tính của đầu vào, rồi ghi kết quả. Đối với tập chọn của chúng ta, hãy kiểm tra số lượng định danh, việc chúng thuộc đầu vào và quy tắc ngưỡng. Một tệp JSON đúng định dạng vẫn có thể chứa sai định danh; chỉ riêng sự hiện diện của nó là chưa đủ.

Hãy dự phòng một lỗi tường minh nếu thiếu tệp đầu vào hoặc nếu đích đến không dùng được. Tránh thay thế những vấn đề này bằng một danh sách rỗng: danh sách đó có thể bị hiểu là một tập chọn hợp lệ. Chương trình phải phân biệt giữa không có kết quả nào đáp ứng ngưỡng và không có kết quả nào vì việc đọc đã thất bại.

6. So sánh trong hai lần chạy hoàn toàn mới

Trước tiên hãy dùng ba dòng mang tính minh họa. Với ngưỡng 0,5, hãy mong đợi b và c; với 0,9, hãy mong đợi một danh sách rỗng; với 0,4, hãy mong đợi cả ba định danh. Những câu trả lời này suy ra từ hợp đồng và không được trình bày như các kết quả đã chạy ở đây. Chúng giúp phát hiện một toán tử so sánh bị đảo hoặc một thứ tự sai.

Sau đó hãy chạy notebook đã khởi động lại và script của bạn trong một tiến trình mới, trên cùng một đầu vào. Hãy so sánh các giá trị hữu ích, không phải ảnh chụp màn hình hay thời gian được ghi trong tệp. Thêm một bộ dữ liệu đại diện thứ hai và một đầu vào không hợp lệ. Hãy ghi lại các khác biệt dự kiến, chẳng hạn như cách trình bày đầu ra tiết chế hơn.

Một thao tác chuyển đổi bằng nbconvert có thể giúp việc di chuyển các cell ban đầu nhanh hơn, nhưng các lệnh magic của nó vẫn có thể còn phụ thuộc vào Jupyter. Hãy loại bỏ hoặc thay thế các chỉ thị riêng của notebook, các phần hiển thị không cần thiết và các cài đặt tùy hứng. Việc xuất ra chỉ là điểm khởi đầu; việc so sánh từ một trạng thái mới quyết định liệu quá trình chuyển đổi đã hoàn tất hay chưa.

7. Chuyển sang GPU mà không đưa trạng thái ẩn trở lại

Khi đã hiểu rõ luồng chạy trên CPU, hãy nối việc tải model và backend vào cùng một cấu trúc tường minh. Hãy giữ nguyên phiên bản, độ chính xác, đầu vào và đích đến. Việc chuyển sang GPU không khắc phục được một thứ tự cell không nhất quán hay một tệp được tạo ra từ một lần thử cũ. Hãy kiểm tra riêng rằng PyTorch thực sự có thể tính toán trên thiết bị đã chọn.

Nếu hai lần khởi chạy tạo ra các giá trị khác nhau, hãy phân biệt một trạng thái bị bỏ sót, một nguồn ngẫu nhiên và các giới hạn số học của phép tính. Một seed không phải là lời hứa phổ quát về sự đồng nhất giữa các phiên bản và phần cứng. Đối với quá trình huấn luyện bị gián đoạn, hãy dùng quy trình dành riêng cho checkpoint: hướng dẫn này biến đổi điểm vào, mà không tái lập lại các trạng thái của optimizer hay của các generator.

Đầu ra hữu ích là một chương trình bạn có thể mô tả bằng một lệnh, kèm theo các điều kiện tiên quyết và một bước kiểm tra kết quả. Notebook vẫn tự do khám phá và trực quan hóa; nó không còn một mình lưu giữ cách mà phép tính phải được khởi chạy.

Câu hỏi của bạn

Có nên từ bỏ notebook để làm cho dự án có thể tái lập không?

Không. Hãy giữ notebook để khám phá và trình bày, nhưng đặt phần tính toán được tái sử dụng vào các hàm hoặc mô-đun mà script cũng gọi tới. Việc kiểm tra phải bắt đầu lại từ một nhân mới và các đầu vào tường minh.

Xuất một notebook sang .py có đủ không?

Không. Việc xuất chỉ di chuyển phần mã hiển thị; nó không sửa được thứ tự các phụ thuộc hay các hiệu ứng của những ô đã chạy. Các lệnh magic vẫn có thể cần Jupyter. Hãy kiểm tra script trong một tiến trình mới.

Tôi có phải thu được các tệp giống hệt nhau từng byte không?

Chỉ khi tiêu chí đó phù hợp với định dạng của bạn. Trước tiên hãy so sánh các định danh, giá trị và quy tắc nghiệp vụ mong đợi. Ngày tháng hoặc siêu dữ liệu có thể khác mà không làm thay đổi phép tính; các dung sai số phải được nêu rõ.