1 điểm bởi GN⁺ 2024-11-30 | 1 bình luận | Chia sẻ qua WhatsApp
  • Đây là dự án tạo mô hình TensorFlow.js để tự động giải CAPTCHA của 4Chan ngay trong trình duyệt, đạt mục tiêu tối thiểu 80% và mục tiêu mong muốn trên 90% độ chính xác
  • Việc thu thập CAPTCHA khó xử lý bằng cách scrape hàng loạt đơn giản do ttl, cd của API yêu cầu, Cloudflare Turnstile và thời gian chờ tăng dần
  • Dịch vụ giải bằng người thật thương mại và gán nhãn thủ công gặp lỗi và bị throttling; dự án tạo khoảng 50.000 ảnh dữ liệu tổng hợp từ khoảng 2.500 nền thực tế và 50–150 ảnh cho từng ký tự để có đủ quy mô huấn luyện
  • Mô hình dùng kiến trúc CNN+LSTM và mã hóa CTC; sau khi huấn luyện bằng Keras/TensorFlow, được chuyển đổi sang TensorFlow.js qua Python 3.10, Keras 2 và định dạng .h5
  • Trong trình duyệt thực tế, lần tải đầu mất khoảng 1 giây, các lần chạy sau gần như tức thì theo cảm nhận, và đạt tỷ lệ thành công trên 90% trên hàng trăm CAPTCHA thực tế

Mục tiêu và mã nguồn công khai

  • Mục tiêu là vừa học machine learning và huấn luyện TensorFlow, vừa tạo một mô hình giải CAPTCHA 4Chan ổn định trong trình duyệt
  • Tiêu chí là độ chính xác tối thiểu 80%, nếu có thể thì trên 90%, và cuối cùng đã đạt được
  • Mã liên quan được công khai trên GitHub tại 4chan-captcha-playground

Cách CAPTCHA của 4Chan hoạt động

  • 4Chan yêu cầu nhập CAPTCHA trước khi viết bài đăng hoặc trả lời
  • CAPTCHA thông thường là ảnh chứa 5–6 ký tự chữ-số, và người dùng phải nhập chính xác tất cả ký tự
  • CAPTCHA dạng thanh trượt hoạt động bằng cách căn khớp ảnh nền trông như các mảnh ký tự ngẫu nhiên với ảnh tiền cảnh có lỗ trong suốt để làm lộ văn bản CAPTCHA

Các giới hạn gặp phải khi thu thập CAPTCHA

  • Khi quan sát yêu cầu CAPTCHA mới, trình duyệt gửi request tới https://sys.4chan.org/captcha?framed=1&board={board}
  • Nếu bỏ framed=1, thay vì postMessage() trong HTML, máy chủ trả về JSON thô
    • JSON bao gồm challenge, ttl, cd, img, img_width, img_height, bg, bg_width, v.v.
    • ttl có vẻ là thời điểm CAPTCHA hết hạn sau khoảng 2 phút
    • cd được hiểu là giá trị cooldown phải chờ đến lần yêu cầu CAPTCHA tiếp theo
  • Nếu gửi yêu cầu liên tiếp, cd ngày càng lớn
    • Những lần đầu có thể yêu cầu mỗi 5 giây
    • Sau đó tăng lên 8 giây, rồi tiếp tục tăng gần như gấp đôi
    • Cuối cùng chạm trần ở 280 giây
  • Sau khi chạm bộ đếm 280 giây, CAPTCHA trở nên khó hơn
    • Xuất hiện ảnh có thêm nhiều đường ngang và nhiễu hình elip
    • Chất lượng dữ liệu thấp hơn nhưng vẫn có thể dùng được
  • Trước khi yêu cầu CAPTCHA cần vượt qua Cloudflare Turnstile
    • Cách dùng nhiều proxy và script đơn giản là không thực tế
    • Script thu thập sao chép cookie Cloudflare từ trình duyệt để dùng, và thay thủ công khi hết hạn
  • Bằng cách này đã thu thập được vài trăm CAPTCHA, nhưng chưa đủ cho huấn luyện và cũng không có nhãn đáp án

Giới hạn của gán nhãn bằng người

  • Việc căn chỉnh CAPTCHA dạng thanh trượt đạt tỷ lệ thành công 100% bằng script heuristic trainer/captcha_aligner.py
  • Tác giả viết trainer/labeler.py để gửi CAPTCHA tới dịch vụ giải CAPTCHA thương mại, cho người thật nhập đáp án
  • Vài chục CAPTCHA đầu tiên gửi đi đa số bị giải sai ít nhất một ký tự
  • Dùng tính năng “100% Recognition” của dịch vụ để chỉ nhận kết quả khi câu trả lời của nhiều worker khớp nhau
    • Giá trị thiết lập là n = 2, x = 2, y = 3
    • Trước tiên gửi cho 2 người; nếu hai người không khớp, gửi thêm tối đa 3 người cho đến khi có hai đáp án trùng nhau
  • Với thiết lập này, khoảng 80% CAPTCHA được giải, trong đó khoảng 90% là chính xác nhưng khoảng 10% có lỗi
    • Có trường hợp nhiều worker mắc cùng một lỗi
  • Cũng dùng userscript để tự mình hoặc nhờ người quen giải CAPTCHA rồi lưu ảnh và đáp án
    • Thu thêm vài trăm ảnh để đưa vào tập huấn luyện
    • Cách tiếp cận này dừng lại do throttling khi yêu cầu lặp lại và CAPTCHA tăng độ khó

Tạo dữ liệu tổng hợp

  • 4Chan và mã CAPTCHA tương ứng không phải mã nguồn mở nên không thể chạy cùng mã đó cục bộ
  • Thay vào đó, dự án tạo CAPTCHA tổng hợp bằng cách xấp xỉ cấu trúc CAPTCHA thực tế
  • CAPTCHA được xử lý thành hai phần: nền và ký tự
    • Nền được lấy bằng cách tìm contour lớn trong ảnh thực tế rồi loại bỏ vùng ký tự
    • Sau khi xóa ký tự, chỉ còn nền nhiễu
  • Từng ký tự riêng lẻ được thu thập bằng gán nhãn thủ công
    • Dùng VoTT để tag ký tự
    • Dùng script đơn giản để trích xuất ký tự và hậu xử lý
    • Thu được 50–150 ảnh tách biệt cho mỗi ký tự
  • CAPTCHA của 4Chan chỉ bao gồm 0, 2, 4, A, D, G, H, J, K, M, N, P, R, S, T, W, X, Y
    • Có khả năng đây là lựa chọn nhằm tránh nhầm lẫn
  • Kết hợp các ký tự và nền đã trích xuất, rồi tạo ảnh tổng hợp theo các mẫu bố trí ký tự đã quan sát
  • Vì ký tự đầu vào đã được gán nhãn, đáp án của CAPTCHA tổng hợp cũng có thể tạo tự động

Kiến trúc mô hình và tiền xử lý

  • Dữ liệu huấn luyện trộn CAPTCHA thanh trượt đã căn chỉnh trước, CAPTCHA thông thường và CAPTCHA tổng hợp
  • Script huấn luyện đưa mọi ảnh về 300x80 pixel và chuyển thành đen trắng thuần
  • Mô hình là kiến trúc LSTM CNN được xây dựng tham khảo từ nhiều bài viết về giải CAPTCHA
    • Dùng 3 lớp convolution/max-pooling
    • Dùng 2 lớp LSTM
    • Cũng thử lớp convolution thứ 4 nhưng hiệu năng không cải thiện
  • Do độ dài đầu ra thay đổi giữa 5 hoặc 6 ký tự, mô hình dùng mã hóa CTC
  • Phần triển khai dùng KerasTensorFlow

Vấn đề thứ tự tham số của tf.image.resize()

  • Một số CAPTCHA thanh trượt đã căn chỉnh cũ không khớp với độ phân giải hoặc tỷ lệ 300x80
  • Script huấn luyện dùng tf.image.resize() để xử lý nhiều loại đầu vào
  • Ban đầu tác giả giả định tham số kích thước là tuple (width, height), nhưng thực tế tf.image.resize() yêu cầu thứ tự (height, width)
  • Lỗi này khiến ảnh bị kéo dọc thành dạng như 80x300, không thể đọc được
    • Dù huấn luyện hơn 32 epoch, hiệu năng trên ảnh đã thấy gần như không có
    • Với CAPTCHA mới, dự đoán gần như ngẫu nhiên
  • Khi trực quan hóa ảnh đầu vào đã xử lý, vấn đề được xác nhận; sau khi sửa, hiệu năng huấn luyện cải thiện mạnh

Quy mô huấn luyện và kết quả

  • Tập dữ liệu cuối cùng gồm khoảng 500 ảnh giải thủ công và khoảng 50.000 ảnh tổng hợp
  • Ảnh tổng hợp được tạo bằng cách lấy mẫu ngẫu nhiên từ khoảng 2.500 ảnh nền và 50–150 ảnh cho từng ký tự
  • Tập dữ liệu được xáo trộn ngẫu nhiên rồi chia theo tỷ lệ 90/10 thành tập huấn luyện và tập đánh giá
  • Trên NVIDIA RTX A4000 Laptop GPU, thời gian huấn luyện mỗi epoch khoảng 45 giây
  • Khi kết thúc epoch đầu, loss ở mức 19 và dự đoán hầu như không đúng
  • Khi kết thúc epoch thứ 4, loss giảm xuống 0,55, và đúng cả 5/5 dự đoán thử nghiệm ngẫu nhiên
  • 8–16 epoch là điểm cân bằng tốt giữa thời gian và hiệu năng cuối cùng
    • Khoảng epoch thứ 8, loss ổn định
    • Sau 16 epoch, mức cải thiện giảm đáng kể
  • Dùng trainer/infer.py để kiểm thử suy luận trong Python, kết quả trên ảnh chưa từng thấy cũng khá hứa hẹn

Chuyển đổi sang TensorFlow.js và chạy trong trình duyệt

  • Userscript được viết bằng TensorFlow.js và TypeScript
  • Thuật toán căn chỉnh CAPTCHA và mã tiền xử lý ảnh từ Python được triển khai lại
  • Mã liên quan nằm trong thư mục user-scripts/ của repository
  • Định dạng mô hình TensorFlow/Keras của Python không tương thích với định dạng mà TensorFlow.js kỳ vọng
  • Cần dùng script chuyển đổi chính thức, nhưng có hai vấn đề
    • Trình chuyển đổi TensorFlow-to-TFJS chính thức không hoạt động trên Python 3.12 và thông báo lỗi cũng không rõ ràng
    • Khi dùng Python 3.10 bằng PyEnv, quá trình chuyển đổi thành công
  • Script chuyển đổi có thể chuyển mô hình Keras 3 sang định dạng TensorFlow.js, nhưng TensorFlow.js thực tế lại không đọc được mô hình đã chuyển đổi đó
  • Cách giải quyết là dùng Keras 2
    • Cài đặt gói legacy tf_keras
    • Đặt biến môi trường TF_USE_LEGACY_KERAS=1 để huấn luyện
    • Xuất ra định dạng mô hình legacy .h5 và chỉ định định dạng đầu vào cho script chuyển đổi
    • Chỉ cần một thay đổi đơn giản một dòng trong mã

Hiệu năng trên CAPTCHA 4Chan thực tế

  • Mô hình cũng hoạt động tốt trên CAPTCHA 4Chan thực tế
  • Lần tải mô hình đầu tiên mất khoảng 1 giây
  • Các lần chạy sau gần như tức thì theo cảm nhận
  • Theo kinh nghiệm giải hàng trăm CAPTCHA thực tế trong trình duyệt, tỷ lệ thành công trên 90%
  • Trường hợp sai ký tự bản thân khá hiếm; khi không chính xác, thường là bỏ sót nguyên một ký tự
  • Có thể cải thiện thêm bằng cách tăng huấn luyện trên dữ liệu thực tế hoặc điều chỉnh layout CAPTCHA của bộ tạo dữ liệu tổng hợp
  • Độ chính xác của mô hình này cao hơn nhiều so với dịch vụ giải CAPTCHA bằng người thật thương mại

CAPTCHA 4 ký tự và kết thúc

  • Trong lúc viết và chỉnh sửa bài sau khi hoàn thành dự án, 4Chan đôi khi bắt đầu cung cấp CAPTCHA 4 ký tự
  • Mô hình chỉ được huấn luyện trên CAPTCHA 5 và 6 ký tự, nhưng vẫn đạt mức hiệu năng tương tự trên CAPTCHA 4 ký tự
  • Trong quá trình dự án, tác giả đã học được nhiều về machine learning và computer vision, đồng thời hoàn thành mô hình giải CAPTCHA trên trình duyệt đúng như mục tiêu ban đầu

1 bình luận

 
GN⁺ 2024-11-30
Ý kiến trên Hacker News
  • Phần tích hợp Keras với TensorFlow.js lộn xộn đúng kiểu TensorFlow
    Mỗi lần dùng TensorFlow, tôi luôn có cảm giác nó giống một loạt công cụ trông có vẻ liên quan được gom đại dưới cùng một mái nhà, hơn là một sản phẩm tích hợp và trơn tru
    Thật ra có thể nói hầu như mọi thư viện hay công cụ mã nguồn mở của Google đều mang cảm giác như vậy

    • Liên quan đến chuyện này, trong bài 15 ngày trước về việc François Chollet rời Google cũng có bối cảnh tương tự: https://news.ycombinator.com/item?id=42130881
      Câu trả lời cho “vì sao năm 2019 lại quyết định sáp nhập Keras vào TensorFlow?” là “đó không phải quyết định của tôi. Đó là quyết định của các lãnh đạo TF vào năm 2018; lúc đó tôi là một cá nhân đóng góp cấp L5, còn đó là quyết định cấp L8”
    • Làm tôi nhớ đến Định luật Conway
  • Tôi cần CAPTCHA để chặn spam ở form bình luận trên trang của mình[0], nên đã tái sử dụng một cách khá thú vị mà tôi từng thấy trước đây
    Nó chắc chắn không hoàn hảo và cũng không khó, nhưng tôi rất thích quá trình làm ra nó
    [0] https://www.hybridlogic.co.uk/contact

  • Có lý do khiến mọi người rời xa CAPTCHA dựa trên văn bản bị bóp méo
    Giờ gần như đã đến điểm máy tính giải chúng giỏi hơn con người
    https://www.usenix.org/system/files/conference/woot14/woot14... là một bài báo về chủ đề này, theo tôi khá thú vị
    Dù vậy, đáng ngạc nhiên là rất nhiều CAPTCHA dạng văn bản vẫn có thể bị giải bằng vài dòng shell script: dùng ImageMagick chuyển sang ảnh xám, xử lý giãn nở và co ảnh, rồi đưa cho Tesseract
    Nhưng cũng có các trang như https://2captcha.net, nên rốt cuộc CAPTCHA gần giống một cơ chế đòi hỏi một chút công sức tối thiểu

    • Việc có thể bị phá về mặt kỹ thuật không có nghĩa là nó vô dụng
      Cách giải trong bài này cũng tốn khá nhiều thời gian, kỹ năng và công sức; kết quả lại không khái quát hóa tốt, nên với loại CAPTCHA khác thì phải làm lại từ đầu
      Phần lớn spammer sẽ không tái hiện được điều này, còn những người có thể làm được thì có khả năng kiếm tiền hợp pháp hoặc nhắm vào mục tiêu sinh lợi hơn
      Những CAPTCHA như vậy vẫn hoạt động tốt trong việc đẩy chi phí spam thành công lên cao hơn lợi nhuận kỳ vọng
    • Tôi tò mò không biết tiếp theo sẽ là gì
      Liệu có thể làm một diễn đàn mà mọi thành viên đều phải phỏng vấn video 15 phút với quản trị viên không? Tôi biết là “không mở rộng được”, nhưng như một cơ chế đùa vui thì có vẻ khả thi
    • Tôi xem CAPTCHA chỉ là một lớp phòng thủ nữa để tăng độ khó cho những tác nhân lạm dụng hệ thống
      Nó không phải giải pháp, mà giống một pháo đài nhỏ đang dần lỗi thời
    • Khó mà gọi là nhỏ
      Theo liên kết, reCAPTCHA v3 mất 10–15 giây và tốn 1,3 USD cho mỗi 1000 CAPTCHA
      Với nhiều tác vụ muốn vượt CAPTCHA, chẳng hạn cào dữ liệu các website lớn ở quy mô lớn, chi phí này thực sự khá lớn và trở nên khó gánh
    • Nếu ở mức đó thì CAPTCHA bằng bằng chứng công việc có lẽ là lựa chọn tốt nhất
      mCaptcha.org là một trong số đó, và cũng có các triển khai khác
      CAPTCHA truyền thống hễ hiệu quả dù chỉ một chút thì rất dễ trở thành cơn ác mộng về khả năng tiếp cận
  • Nếu bạn quan tâm đến chủ đề kiểu này, tôi cũng có một phân tích về Silk Road CAPTCHA mà tôi đã tổng hợp năm 2014: https://github.com/mieko/sr-captcha

  • Cách 4chan phản ứng trông có vẻ hợp lý
    Dù sao thì mạng nơ-ron cũng giải được dễ dàng, nên họ chọn đơn giản hóa phần việc giao cho con người
    Giờ dù thiết kế CAPTCHA cực khó thì khả năng làm máy khó giải cũng thấp, còn xác suất chỉ khiến con người bực hơn lại cao

    • Vậy thì họ cũng có thể chặn hẳn việc đăng bài của người dùng miễn phí, và buộc tất cả những ai muốn đăng phải mua 4chan Pass giá 20 USD/năm
      https://4chan.org/pass
      Nó vốn đã được cung cấp như một tùy chọn để đăng bài không cần CAPTCHA
      Nếu CAPTCHA hoàn toàn vô hiệu, kết luận kéo theo là nên bỏ CAPTCHA và đăng bài miễn phí, còn ai muốn đăng thì đều phải mua 4chan Pass
    • Có vẻ chúng ta đã mắc kẹt ở điểm đó ít nhất 5 năm, có khi tới 10 năm rồi
    • Tiếp theo cứ dùng quét võng mạc Worldcoin là xong
    • 4chan không mấy quan tâm con người có bực hay không
      Gần đây họ đưa vào độ trễ đăng bài 15 phút, thật sự rất bực
      Tôi đã phải đưa 4chan vào danh sách cho phép trong Cookie AutoDelete
  • Có lẽ giả vờ như có CAPTCHA, nhưng thực ra phân tích thời điểm và hành vi của người dùng thì tốt hơn chăng
    Nói thật là tôi cũng có cảm giác chuyện đó đã đang xảy ra rồi
    Nếu đi theo hướng hoàn toàn meta, cũng có thể huấn luyện AI để phán đoán xem tác nhân ở phía bên kia có phải là người hay không
    Tức là coi như phát minh ra một bài kiểm tra Turing ngược, theo kiểu nếu AI không phân biệt được với phản hồi của một người bình thường thì xem là người
    Điểm khác là không phải phân biệt với phản hồi của con người dùng cho mục đích marketing
    Chỉ nghĩ đến chuyện này thôi đã thấy hơi buồn nôn, chắc phải đi nằm

    • Các nhà cung cấp CAPTCHA lớn nhìn chung đã làm như vậy rồi
      Trước cả khi hiển thị CAPTCHA, họ đã nhận diện trước dấu vân tay TLS, IP, HTTP/2, request, môi trường JavaScript, khả năng render phông chữ và hình ảnh, cũng như chính trình duyệt
      Họ dùng các thông tin này để tính điểm tin cậy, rồi quyết định ngay từ đầu có hiển thị CAPTCHA hay không
      Sau đó việc phân tích phần nhập CAPTCHA mới có ý nghĩa, nhưng đến thời điểm đó thì có thể coi là đã bắt được 90% bot rồi
      Lượng thông tin mà trình duyệt có thể báo cho máy chủ mà không hề nhận thức gì là phi lý đến mức dấu vân tay số của mỗi chúng ta có khi còn độc nhất hơn cả dấu vân tay thật
    • Đó chính là việc reCAPTCHA đang làm
  • Tôi vẫn cho rằng trường hợp gốc thuộc hàng kinh điển của việc vượt CAPTCHA 4chan là Yannick Kilcher fine-tune GPT-J bằng dataset “Raiders of the Lost Kek”
    Có thể đây là một trong những ví dụ hay nhất về việc dùng mô hình ngôn ngữ lớn từng được đưa lên video: https://youtu.be/efPrtcLdcdM?si=errY0PrEhnX9ylDw

    • Chỉ riêng phần tuyên bố miễn trừ trách nhiệm và cảnh báo về 4chan đã kéo dài gần 1 phút
      Đáng được ghi vào kỷ lục
  • Vì những chuyện như “bộ chuyển đổi mô hình TensorFlow-to-TFJS chính thức không hoạt động trên Python 3.12 và tài liệu cũng không được viết đàng hoàng”, “TensorFlow.js không hỗ trợ Keras 3”, vài năm trước tôi định thử làm machine learning nhẹ nhàng mà gần như bỏ cuộc
    Có quá nhiều tutorial mới nhất thực ra đã lỗi thời, quá nhiều bẫy ngẫu nhiên, và thật sốc khi nhiều hướng dẫn “bắt đầu” lại mặc định rằng bạn đã là chuyên gia

    • Với tư cách là người đã làm machine learning vài năm, tôi muốn khuyên nên tránh các trào lưu mới nhất
      Tốt hơn là học nền tảng từ một giáo trình thống kê Bayes cũ, rồi sau đó chuyển sang các framework chính như PyTorch
      Ban đầu nên tự viết mọi phần của các kiến trúc CNN, RNN, Transformer và pipeline huấn luyện
      Bao gồm cả data loader, nhưng có thể bỏ qua CUDA matrix kernel
      Nên tránh xa những wrapper bọc lại wrapper của người khác như LangChain
      Tài liệu không chỉ lỗi thời, mà nhiều khi còn sai hẳn về những kiến thức nền tảng
      Hugging Face rất tuyệt nếu bạn nắm được cơ bản và có thể sửa khi wrapper chuẩn bị hỏng
  • Chuyện này giống như bỏ ra vài giờ để học cách mở nắp bể phốt

    • Lạ là phần lớn 4chan cho cảm giác ít làm mục não hơn cả Twitter trước thời Musk
    • Không nên đánh giá thấp những điều có thể học được khi nghiên cứu hệ thống bể phốt
  • Nếu lần theo liên kết tới các dịch vụ giải CAPTCHA, bạn có thể đọc hồ sơ của những người làm công việc đó
    Nó được quảng bá theo kiểu việc này có đạo đức hơn so với làm trong các nhà máy nguy hiểm