Phác họa bài post:
⓪
Đề dẫn.
①
OpenAI Codex.
②
AlphaCode.
➡
Thể lệ thi.
➡
Cách tiếp cận.
➡
Máy đi thi.
Đọc thêm ⇛
➡
Code Generation.
➡
GitHub Copilot.
-
Để giúp anh/chị
quyết định có đọc tiếp hay không, tôi xin phép cung cấp các thông tin liên quan
đến bài post này như sau:
·
Chủ
đề: Machine Learning.
·
Tính
thời sự: Tháng 02/2022.
·
Thời
gian đọc: Đọc hết: 7
phút, đọc lướt ý chính: 3 phút.
~
Hôm nay xin
phép anh/chị chúng ta đàm luận về chủ đề “máy lập trình” (Machine
Programming). Chủ đề này có vẻ quá khủng khiếp, đúng không ạ? Tôi tin là
trên diễn đàn này nhiều anh/chị đã có trải nghiệm lập trình, thậm chí là tham
gia nhiều cuộc thi lập trình. Để làm cho máy có thể lập trình được như người
thì trước đây có thể nói là khoa học viễn tưởng. Ấy thế mà cách đây chừng hơn một
tháng, báo chí ta và Tây đều rộ lên việc công ty DeepMind (một công ty con của
Google) đã tạo ra một phần mềm có thể tham gia thi lập trình như người và điều
gây ngạc nhiên hơn cả là “lập trình viên” này đạt trình độ “trung bình” so với
tập hợp các thí sinh (người thật) tham gia! Thực hư thế nào, anh/chị có thể
tham khảo bài báo của họ ở đây: Competition-Level Code Generation with
AlphaCode. Nếu anh/chị
đọc bài báo này rồi thì có thể bỏ qua phần tiếp theo bài post của tôi, vì tôi
chỉ “diễn nôm” lại ý tưởng của họ. Nếu anh/chị chưa đọc thì tôi xin phép cung cấp
thêm thông tin: bài báo của họ dài 74 trang, nội dung chính khoảng 31 trang,
còn lại là tham chiếu và phụ lục.
░
⓪ Đề dẫn.
Đối với người
“ngoại đạo” thì khái niệm “lập trình” nghe có vẻ bí hiểm và cao siêu, chứ đối với
anh/chị trên diễn đàn này thì việc lập trình cũng “thường” thôi, đúng không ạ? 😊 Khi chúng ta học lập trình, thầy/cô dạy
là phải xác định mục tiêu, chức năng của chương trình trước, rồi mới ngồi vào
viết chương trình. Chúng ta cũng được khuyến nghị rằng một vấn đề lớn và khó thì
trước hết cần chia vấn đề thành nhiều phần nhỏ, dễ hơn. Khi vấn đề không thể
chia nhỏ hơn nữa (vấn đề “nguyên tử” - nhỏ nhất) thì cách thường được áp dụng
là thiết kế thành các module, sub-routine hoặc function. Và khi
viết phần mã lập trình (trong bất cứ ngôn ngữ lập trình nào), thói quen “chuẩn”
mà chúng ta thường được khuyến nghị là viết thuyết minh trước, lập trình sau.
Ngẫm nghĩ một
chút, chúng ta thấy lập trình từa tựa như viết bài post gửi lên diễn đàn này vậy.
Chỉ có điều là chúng ta phải viết theo ngôn ngữ lập trình như C, C++, Python,
Java, PHP, … chứ không phải viết tiếng Việt. Muốn máy compile/interpret
(biên dịch/thông dịch) không phát sinh lỗi, chúng ta phải viết đúng chính tả,
đúng ngữ pháp (cú pháp). Khi cho chương trình chạy (run) chúng ta lúc đó
kiểm tra (test) xem chương trình đó có chạy “đúng” hay không? Và thông
thường cũng phải xem xem có bao nhiêu trường hợp chạy đúng, bao nhiêu trường hợp
chạy sai, … Đại ý thế.
Một cách nôm na
ngắn gọn, theo các thông lệ thực tiễn tốt (good practices) về lập trình,
chúng ta có thể hiểu giản lược như sau:
[Đề bài/thuyết
minh] →
[Đoạn mã chương trình] → [Kiểm tra kết quả]
░
① OpenAI Codex.
Trước khi bàn đến
cách tiếp cận của AlphaCode, mời anh/chị cùng xem qua cách OpenAI Codex tạo mã
chương trình viết trong ngôn ngữ Python. Bài báo của họ tập trung vào cách tạo
mã như sau:
[Docstring] → [Python function] → [Tests]
Trong đó:
·
Docstring:
là thuyết minh (thường xuất hiện trước khi viết mã chương trình)
·
Python function:
là mã của một hàm viết trong ngôn ngữ lập trình Python
·
Tests: là phần kiểm tra xem phần mã vừa tạo ra chạy
đúng ở mức độ nào.
Họ lấy mô hình
gốc là GPT-3. Tôi đã giới thiệu mô hình GPT-3 trong bài post ngày
26-01-2022 với chủ đề là máy hiểu ngôn ngữ tự nhiên (Natural Language Understanding).
Với khả năng của GPT-3, khi cho một chủ đề, GPT-3 có khả năng “viết” một “bản
tin” không khác một nhà báo thực thụ là bao. Người ta tận dụng khả năng này của
GPT-3. Nếu GPT-3 có khả năng viết một bản tin thì nó cũng có khả năng viết một
đoạn mã chương trình khi cho một đầu vào thích hợp. Cái khác là GPT-3 chỉ được
huấn luyện với dữ liệu ngôn ngữ tự nhiên – tức là đầu vào là ngôn ngữ tự nhiên
và đầu ra cũng là ngôn ngữ tự nhiên thì Codex lấy đầu vào là ngôn ngữ tự nhiên
(tiếng Anh) cho đầu ra là ngôn ngữ lập trình (Python). Tất nhiên, dữ liệu huấn
luyện Fine-tuning phải tìm một nguồn thích hợp. Nguồn đó chính là GitHub (dung lượng 159 GB thu thập từ 54 triệu
kho phần mềm công khai).
Vậy “trí tuệ” của
Codex nằm ở đâu? Đó là câu hỏi “tò mò” chúng ta thường đặt ra, đúng không
anh/chị?
Câu trả lời ngắn:
lấy từ dữ liệu (kho dữ liệu khổng lồ).
Câu trả lời dài
hơn: dữ liệu trên kho GitHub được dán nhãn như sau:
·
Với
Docstring1 thì người lập trình viết đoạn mã Code1
·
Với
Docstring2 thì người lập trình viết đoạn mã Code2
·
…
·
Với
Docstring1000000 thì người lập trình viết đoạn mã Code1000000
·
…
Lưu ý: các Docstring1, Docstring2,
…, Docstring1000000 là các thuyết minh bằng tiếng Anh.
Sau khi huấn
luyện Fine-tuning với tập mẫu trên, khi cho một Docstring_mới thì máy sẽ biết cách tạo ra một Code_mới. Đơn giản là vậy. 😊
░
② AlphaCode.
Cách đặt vấn đề
của nhóm nghiên cứu thuộc công DeepMind hơi khác so với Codex: máy tham gia cuộc
thi lập trình. Tất nhiên, máy cũng giống như người, phải tuân theo đúng quy định,
thể lệ của cuộc thi.
➡ Thể lệ thi.
Để hiểu máy thi
lập trình như thế nào, mời anh chị cùng tìm hiểu qua hình thức
thi trực tuyến. Cách tổ chức thi mỗi nơi một khác nhưng nhìn chung là thế này:
người ta cho một đề thi, thường gồm 5-10 “vấn đề”, thời gian thi khoảng 3 tiếng
đồng hồ. Người thi (hoặc nhóm thi) cần giải được càng nhiều “vấn đề” càng tốt.
Đoạn mã chương trình, khi “nộp bài”, được gửi lên máy chủ (server). Tại
đây, chương trình sẽ cho chạy thử hàng loạt test (các test này ẩn, thí sinh
không biết). Thí sinh sẽ được thông báo là bài làm của họ có vượt qua được các
test hay không (người ta không giải thích lý do vì sao được hay không được). Điểm
chấm là tổ hợp của số kết quả đúng và thời gian chạy mỗi “vấn đề”. Mỗi một “vấn
đề” gắn với một hệ số. Vấn đề càng khó thì hệ số càng cao. Ngôn ngữ lập trình
thường dùng trong các cuộc thì là C++, Python.
Thế một “vấn đề”
được người ta đặc tả như thế nào? Cấu trúc đặc tả chung như sau:
·
Mô
tả vấn đề
·
Đặc
tả dạng thức đầu vào (input), đầu ra (output)
·
Cho
một số mẫu ví dụ về đầu vào (input), đầu ra (output).
Tôi có đính kèm
một file là đặc tả đề thi có tên là “Backspace” – là một ví dụ về đề thi, để
chúng ta dễ hình dung. (Ví dụ này tôi lấy từ bài báo AlphaCode.)
-
➡ Cách tiếp cận.
Nếu anh/chị bỏ
chút thời gian đọc đề thi (như ví dụ đã dẫn), thì chúng ta sẽ có cảm giác là đến
người có nhiều thời gian ngồi lập trình “mòn cả ghế” còn thấy khó thì máy làm
sao mà làm được nhỉ? Tuy nhiên, nếu chúng ta nhớ lại cách tiếp cận của dịch
máy: phiên dịch văn bản từ ngôn ngữ này sang ngôn ngữ khác bằng cách học theo
các bài dịch do người thật dịch (cả hai phương pháp SMT (Statistical Machine
Translation) và NMT (Neural Machine Translation) có cùng cách tiếp cận),
thì chúng ta dễ dàng nhận thấy vấn đề này hoàn toàn tương tự như dịch máy. Nếu chúng
ta coi “đề thi” được viết trong ngôn ngữ tự nhiên (tiếng Anh) thì bài toán trên
trở thành: phiên dịch đoạn văn bản tiếng Anh (đề thi) ra đoạn văn bản được viết
bằng ngôn ngữ lập trình (phần lập trình tham gia cuộc thì)!
Chúng ta có thể
mô tả một cách giản lược như sau:
[Đề thi (tiếng Anh)] → [Đoạn mã lập trình (C++, Python, …)]
Trong dịch máy
(Machine Translation) người ta tách đoạn văn bản gốc thành từng câu và
máy dịch từng câu một. AlphaCode có cách tiếp cận tương tự: họ tách đề thi
thành từng “vấn đề” và người ta phiên dịch từng “vấn đề” thành “giải pháp” –
“giải pháp” chính là đoạn mã lập trình:
[Vấn đề] → [Giải pháp]
-
▓ Dữ liệu huấn luyện DeepMind lấy ở đâu? Đến
đây, chắc hẳn anh/chị cũng đoán được rồi: họ lấy dữ liệu từ các cuộc thi. AlphaCode
học theo cách tiếp cận của Codex, nhưng để mô hình có thể “thi” được, kiến trúc
của AlphaCode có khác so với cách tiếp cận dịch máy thông thường. Một cách khái
quát, kiến trúc này bao gồm 4 bước:
Bước 1: Huấn
luyện Pre-training (dữ liệu autoregressive: tự động tiếp diễn). Dữ
liệu lấy từ GitHub – dữ liệu không dán nhãn. Mục tiêu của
bước này là để mô hình “thông thạo” ngôn ngữ lập trình! Nếu anh/chị nhớ lại
cách tiếp cận của GPT và BERT (bài tôi post lên diễn đàn này (ICT_VN) ngày
26-01-2022) thì đây là bước mà mô hình “nạp” tri thức – tức là hiểu biết về lập
trình ở mức độ khái quát.
Bước 2: Huấn
luyện Fine-tuning. Dữ liệu lấy từ các cuộc thi và dán nhãn: “vấn đề” →
“giải pháp” – “vấn đề” được viết bằng tiếng Anh, còn “giải pháp” được viết bằng
ngôn ngữ lập trình (C++, Python). Anh/chị có thể hình dung tập mẫu dữ liệu một
cách tượng trưng như sau:
[Vấn đề 1] → [Giải pháp 1]
[Vấn đề 2] → [Giải pháp 2]
…
[Vấn đề 1000000] → [Giải pháp 1000000]
…
Đến
đây, khi chúng ta cấp đầu vào là “vấn đề”
thì mô hình sẽ cho đầu ra “giải pháp”.
“Giải pháp” là đoạn mã chương trình viết trong
ngôn ngữ lập trình C++ hoặc Python.
Bước 3: Tạo
một lượng lớn “giải
pháp” từ một “vấn đề”. Anh/chị có thể chất vấn: sao cần làm
bước này làm gì? Trả lời: khi đi thi, từ một “vấn đề”,
người thi có thể nộp nhiều “giải pháp”.
Chú ý rằng, “giải
pháp” có thể đúng, có
thể sai. Vì vậy, khi nộp nhiều “giải pháp”
thì xác suất có “giải
pháp” đúng sẽ cao hơn.
Từ một “vấn đề”, họ tạo ra hàng triệu “giải pháp” cho “vấn đề”
đó. Khoảng một nửa số “giải pháp”
được viết bằng ngôn ngữ C++, số còn lại được viết bằng Python.
Bước 4: Đối
với cuộc thi mà AlphaCode tham dự, với mỗi “vấn đề”
họ chỉ được phép nộp tối đa là 10 “giải pháp”.
Vì vậy, họ phải chọn 10 “giải pháp”
tốt nhất để nộp bài. Đối với anh/chị tò mò về kỹ thuật thì cách họ làm có 2 bước:
lọc (Filtering) và phân cụm (Clustering). Tôi xin phép không đi
sâu vào chi tiết nhưng bản thân bài toán chọn ra 10 “giải pháp” tối ưu cũng đã
là một câu chuyện thú vị.
-
➡ Máy đi thi.
·
Địa
điểm thi: Codeforces.
·
Thời
gian thi: từ ngày 01/12/2021 đến ngày 28/12/2021.
·
Số
lần tham gia thi: 10.
·
Số
thí sinh tham gia: 5,000+.
Người ta xếp hạng
các thí sinh theo thang 100. Thí sinh giỏi nhất đứng hạng 1 (thứ nhất) và thí
sinh kém nhất đứng hạng 100. Thế máy AlphaCode đứng hạng bao nhiêu? Vì tham gia
10 cuộc thi nên họ phải tính thứ hạng chung cho cả 10 cuộc thi: thứ 54.3 – dưới
trung bình một tý.
Nếu nộp nhiều
hơn 10 “giải pháp” (chỉ để thử hệ thống của họ - khi thi thì không được phép),
AlphaCode đạt được thứ hạng 48.8 – trên trung bình (50) hơn 1 điểm phần trăm.
⚠ Chú
ý: khi đọc báo, chúng ta thấy các báo đưa tin máy đi thi đạt 54.3%. Con số
54.3% rất dễ gây hiểu nhầm: số % càng cao thì máy càng giỏi. Không phải vậy. Ngược
lại mới đúng: số % càng thấp thì thứ hạng càng cao, máy càng giỏi.
<Mở ngoặc>:
Đến
như một nghiên cứu khoa học, các nhà khoa học thời nay cũng biết cách “giật
tít”, gây sốc cho người đọc! 😊
</Đóng ngoặc>
░
Đọc thêm ⇛
Bàn về ứng dụng
các mô hình Codex và AlphaCode vào thực tế. Về cơ bản, tôi hy vọng là anh/chị đã biết được thực hư
câu chuyện “máy thi lập trình” như thế nào rồi. Bài post của tôi đã kết thúc.
Bây giờ tôi xin phép bàn thêm là liệu các mô hình Codex, AlphaCode có ứng dụng được
vào việc gì không?
➡ Code Generation.
Trước khi bàn đến
ứng dụng, chúng ta hãy cùng rà soát lại cách Codex và AlphaCode “lập trình”. Về
bản chất, các mô hình này “tạo mã lập trình” – trong tiếng Anh người ta gọi là Code
Generation. Nếu anh/chị nhớ lại, Code Generation đã được nhiều công
ty tìm cách tiếp cận từ khá sớm. Theo hiểu biết của tôi thì sớm nhất có lẽ là
phần mềm của IBM có tên là Rational Rose. Rational Rose lấy đầu
vào là UML (Unified Modeling Language) và đầu ra là một “khung phần mềm” gồm
nhiều thứ, trong đó có các đoạn mã chương trình. Hay như Oracle, người lập
trình có thể tạo mã phần mềm (chương trình được viết bằng ngôn ngữ Java) xuất
phát từ cấu trúc của một bảng (table) trong một cơ sở dữ liệu (database).
Phần mềm được tạo ra này có hàng loạt chức năng như thêm bớt, sửa đổi, liệt kê
các bản ghi (record) của chính bảng đó. Chẳng hạn, nếu có thời gian và
tò mò, anh/chị có thể tham khảo ở đây.
-
Quan sát hai giải
pháp trên (Rational Rose và Oracle), chúng ta để ý thấy có một điểm
khác so với cách tạo mã của Codex và AlphaCode:
Rational
Rose: [UML]
→
[Mã chương
trình]
Oracle: [CSDL] → [Mã chương trình]
Nghĩa là khác
nhau ở đầu vào. Rational Rose và Oracle cần người dùng phải có kiến
thức về kỹ nghệ phần mềm (software engineering), cụ thể là phải biết
ngôn ngữ UML hoặc phải có kiến thức về cơ sở dữ liệu. Còn Codex và AlphaCode chỉ
cần người dùng biết viết tiếng Anh, mà cũng chỉ cần ở mức cơ bản thôi! (Trong
tương lai tôi hy vọng có ai đó, hoặc nhóm nào đó, chuyển ngữ từ tiếng Việt sang
tiếng Anh, tiếp theo dùng các mô hình như Codex/AlphaCode để chuyển ngữ từ tiếng
Anh ra các đoạn mã lập trình. 😊)
Codex,
AlphaCode: [Ngôn ngữ tự nhiên]
→
[Mã chương
trình]
-
➡ GitHub Copilot.
Vào thời điểm
hiện nay, đoạn mã lập trình do Codex hoặc AlphaCode tạo ra chưa chắc đã đúng cú
pháp (nghĩa là chưa chắc đã compile). Và nếu đã đúng cú pháp rồi thì đoạn
mã đó chưa chắc đã chạy đúng (đúng logic). Nghĩa là chẳng có gì đảm bảo để mã tạo
ra “chạy” được cả. Tuy không chắc chắn đúng, nhưng rõ ràng là chúng có thể đưa
ra gợi ý rất tốt cho người lập trình. Đó là ý tưởng mà Codex đã phối hợp với
GitHub đưa ra một ứng dụng khá hấp dẫn: Your
AI pair programmer
(tạm dịch: AI song hành lập trình cùng bạn). Đại ý nó giống như autocomplete:
khi soạn thảo chương trình, người lập trình gõ một đoạn văn bản khởi đầu, máy sẽ
đoán ý người lập trình, rồi nó đưa ra gợi ý cho phần tiếp theo. Phần gợi ý của
AI thường áp dụng cho hàm (function) – đầy đủ từ đầu đến cuối! Nó chỉ gợi
ý thế thôi, còn đoạn mã mà nó gợi có đúng cú pháp hay không, đoạn đấy có chạy
đúng hay không thì trách nhiệm thuộc về người lập trình. Tức là trách nhiệm
chính là người lập trình còn bạn “AI song hành” kia chỉ đóng vai “nghe nhạc hiệu
– đoán chương trình” (nhại một chương trình của VTV trước đây). Nhưng như thế
cũng quý lắm rồi! 😊
<Mở ngoặc>
GitHub
Copilot đang ở giai đoạn technical preview. Nếu anh/chị muốn thử trải
nghiệm thì anh/chị phải đăng ký (Sign Up). Tôi đã đăng ký và có một vài
trải nghiệm tuy đơn giản nhưng cũng thú vị. Tôi xin kể ra đây quá trình đăng ký
của tôi để anh/chị nếu hứng thú thì cùng thử cho vui:
·
Trước
hết, anh/chị cần có một tài khoản trên GitHub (đăng ký miễn phí).
·
Phần
cuối trang GitHub Copilot, anh/chị kích chuột vào đường link Sign up for the technical preview.
·
Tiếp
theo là đợi … Tôi đợi khá lâu, hình như 10 ngày hay 2 tuần gì đó. Chắc người ta
còn phải kiểm tra một số tiêu chí trước khi quyết định chấp nhận hay không.
·
Sau
đó, họ gửi một thư phúc đáp vào địa chỉ email mà anh/chị đã đăng ký GitHub.
·
Trong
thư phúc đáp, người ta có đầy đủ hướng dẫn cho anh/chị để trải nghiệm việc
Codex hỗ trợ coding như thế nào.
·
Việc
thử nghiệm chạy trong phần mềm Visual Studio Code (là phần mềm soạn thảo dành cho các
ngôn ngữ lập trình).
·
Như
tôi trải nghiệm thì GitHub Copilot gợi ý bằng hai cách: dựa trên tên hàm (function
name) và dựa trên thuyết minh (comments). Tất nhiên, cả tên hàm và
thuyết minh đều phải viết bằng tiếng Anh.
</Hết mở ngoặc>
⁇ Anh/chị
thế nào chả đặt câu hỏi: Liệu Code Generation, theo cách tiếp cận của
Codex hoặc AlphaCode, đến một lúc nào đó tạo ra chương trình luôn luôn đúng cú
pháp và chạy theo đúng ý muốn của người lập trình không? Trả lời: theo ý
kiến của cá nhân tôi thì: “còn lâu nhé”! Vì sao vậy? Vì nếu chúng ta
“soi kỹ” cách tiếp cận thì các mô hình loại này tích hợp tri thức từ các website
lập trình công khai (như GitHub) hoặc các cuộc thi (như Codeforces). Có một thực
tế: mã lập trình từ các nguồn này không phải đúng 100%. Vì là các website mở và
công khai nên nguồn đầu vào không thể kiểm soát được các đoạn mã đó có lỗi hay
không lỗi. Và có một điểm khó hơn nữa: không có cách gì để biết được, một cách
tự động, đoạn mã đó có chạy đúng như ý muốn hay không.
░
Trong một buổi
sáng bình yên, và đầy suy ngẫm, chú thỏ “ảo” thay tôi xin phép mời anh/chị một
tách cà phê.
(\_/)
(
•_•)
/
>☕