<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dinh Truong Phan</title>
    <description>The latest articles on DEV Community by Dinh Truong Phan (@dtruong46me).</description>
    <link>https://dev.to/dtruong46me</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1172367%2F1cf06b8a-e73f-41d7-af7c-9645cf282143.jpg</url>
      <title>DEV Community: Dinh Truong Phan</title>
      <link>https://dev.to/dtruong46me</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dtruong46me"/>
    <language>en</language>
    <item>
      <title>Tìm Hiểu Về RAG: Công Nghệ Đột Phá Đang "Làm Mưa Làm Gió" Trong Thế Giới Chatbot</title>
      <dc:creator>Dinh Truong Phan</dc:creator>
      <pubDate>Tue, 03 Sep 2024 04:31:46 +0000</pubDate>
      <link>https://dev.to/dtruong46me/tim-hieu-ve-rag-cong-nghe-dot-pha-dang-lam-mua-lam-gio-trong-the-gioi-chatbot-nl7</link>
      <guid>https://dev.to/dtruong46me/tim-hieu-ve-rag-cong-nghe-dot-pha-dang-lam-mua-lam-gio-trong-the-gioi-chatbot-nl7</guid>
      <description>&lt;h3&gt;
  
  
  Bạn Đã Nghe Về RAG Chưa?
&lt;/h3&gt;

&lt;p&gt;Trong kỷ nguyên mà công nghệ trí tuệ nhân tạo (AI) không ngừng bùng nổ, mỗi ngày lại có thêm những thuật ngữ mới xuất hiện. Một trong số đó là RAG, viết tắt của "Retrieval-Augmented Generation". Đừng để cái tên này đánh lừa bạn! Đây không phải là "rác" mà là một kỹ thuật đột phá, kết hợp giữa truy xuất thông tin (retrieval) và tạo ra nội dung (generation), mang lại kết quả chính xác và phong phú hơn.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tại Sao RAG Lại Là Công Nghệ Đáng Chú Ý?
&lt;/h3&gt;

&lt;p&gt;Với sự ra đời của các mô hình ngôn ngữ lớn như ChatGPT hay Gemini, nhu cầu cá nhân hóa chatbot đang bùng nổ. Các doanh nghiệp hiện nay không chỉ muốn chatbot của họ trả lời được những câu hỏi cơ bản mà còn có khả năng truy cập và sử dụng các thông tin nội bộ. Đây chính là lý do RAG trở thành một công nghệ chủ chốt, giúp biến chatbot từ một công cụ hỗ trợ đơn thuần thành một phần không thể thiếu trong chiến lược kinh doanh.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cấu Trúc Cơ Bản Của RAG
&lt;/h3&gt;

&lt;p&gt;Hình 1: Mô hình Retrieval-Augmented Generation&lt;br&gt;
RAG hoạt động dựa trên một pipeline đơn giản nhưng cực kỳ hiệu quả, bao gồm ba bước chính:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Xây dựng Vector Store (Embeddings)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Đây là bước đầu tiên và quan trọng nhất. Các tài liệu như văn bản, PDF, hay dữ liệu từ bảng biểu được chuyển đổi thành các vector trong một không gian đa chiều và được lưu trữ trong &lt;strong&gt;vector database&lt;/strong&gt;. Trong không gian này, các tài liệu tương tự sẽ nằm gần nhau, giúp việc truy xuất trở nên dễ dàng hơn. Các văn bản thường được chia thành các đoạn nhỏ (chunks) và qua các mô hình embeddings để tạo ra các vectors đại diện.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Truy vấn và tìm kiếm thông tin (Retriever)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bước tiếp theo là xây dựng một hệ thống truy vấn hiệu quả. Hệ thống này cần nhanh, chính xác và tiết kiệm chi phí. Các thuật toán như &lt;strong&gt;BM25&lt;/strong&gt; hay &lt;strong&gt;Cosine Similarity&lt;/strong&gt; được sử dụng để tìm ra các tài liệu liên quan nhất trong thời gian ngắn nhất.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tạo nội dung (Generation)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Đây là phần mà các mô hình ngôn ngữ lớn như &lt;strong&gt;ChatGPT&lt;/strong&gt; hay &lt;strong&gt;Gemini&lt;/strong&gt; phát huy sức mạnh. Sau khi đã có các tài liệu liên quan, hệ thống sẽ kết hợp chúng với câu hỏi ban đầu để tạo ra câu trả lời. Phần này khá dễ dàng nếu bạn có một mô hình tốt, nhưng nó cũng đòi hỏi chi phí đầu tư cao.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Những Thách Thức Khi Triển Khai RAG
&lt;/h3&gt;

&lt;p&gt;Dù RAG có vẻ là một giải pháp hoàn hảo, nhưng khi bước vào triển khai thực tế, bạn sẽ gặp không ít thách thức. Dưới đây là những vấn đề phổ biến mà bạn cần lưu ý:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Xử lý dữ liệu phức tạp&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Không phải tất cả dữ liệu đều là văn bản đơn giản. Dữ liệu dạng bảng biểu hay hình ảnh đòi hỏi các phương pháp xử lý đặc biệt hơn. Đây là lúc &lt;strong&gt;Tabular RAG&lt;/strong&gt; xuất hiện để giúp xử lý những dữ liệu phức tạp này.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Kỹ thuật chia văn bản (Chunking)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Việc chia nhỏ văn bản thành các đoạn (chunks) là yếu tố then chốt. Độ dài lý tưởng của mỗi đoạn là bao nhiêu? Điều này phụ thuộc vào loại dữ liệu và yêu cầu cụ thể của từng ứng dụng. Những kỹ thuật như &lt;strong&gt;Chunking RAG&lt;/strong&gt; và &lt;strong&gt;Metadata filtering&lt;/strong&gt; sẽ giúp bạn tối ưu hóa quy trình này.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Truy xuất tài liệu&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Khi truy xuất tài liệu, xác định số lượng tài liệu cần thiết là một bài toán khó. Quá nhiều tài liệu có thể gây ra tình trạng bias, khi mô hình chỉ tập trung vào những tài liệu đầu tiên hoặc cuối cùng. Để giải quyết, bạn có thể tìm hiểu về &lt;strong&gt;Query Translation&lt;/strong&gt; hay &lt;strong&gt;Documents filtering&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Hiệu suất của hệ thống truy vấn, quản lý và cập nhật dữ liệu, bảo mật và quyền riêng tư&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Khi số lượng tài liệu tăng lên, hiệu suất của hệ thống truy vấn có thể bị suy giảm, đặc biệt khi phải phục vụ nhiều người dùng cùng lúc. Đồng thời, việc quản lý và cập nhật dữ liệu trong vector database để phản ánh chính xác các thay đổi liên tục cũng là một thách thức lớn. Hơn nữa, bảo mật và quyền riêng tư cũng là mối quan tâm hàng đầu, đặc biệt khi RAG xử lý các dữ liệu nhạy cảm. Tất cả những yếu tố này đòi hỏi phải có sự tối ưu hóa và quản lý cẩn thận.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Kết Luận
&lt;/h3&gt;

&lt;p&gt;RAG không chỉ là một thuật ngữ thời thượng mà là một công nghệ có tiềm năng to lớn trong việc nâng cao hiệu quả của các hệ thống chatbot. Mặc dù có nhiều thách thức trong việc triển khai, nhưng với sự phát triển liên tục của công nghệ, RAG hứa hẹn sẽ còn tiến xa hơn trong tương lai, trở thành một công cụ không thể thiếu cho các doanh nghiệp muốn dẫn đầu trong kỷ nguyên số.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hãy cùng khám phá và áp dụng RAG để biến những thách thức thành cơ hội, đưa doanh nghiệp của bạn tiến xa hơn trong hành trình số hóa!&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[LDC-24.08.2024] 564. Find the Closest Palindrome: Hướng Dẫn Từ Đầu Đến Cuối</title>
      <dc:creator>Dinh Truong Phan</dc:creator>
      <pubDate>Sat, 24 Aug 2024 11:47:34 +0000</pubDate>
      <link>https://dev.to/dtruong46me/ldc-24082024-564-find-the-closest-palindrome-huong-dan-tu-dau-den-cuoi-pnh</link>
      <guid>https://dev.to/dtruong46me/ldc-24082024-564-find-the-closest-palindrome-huong-dan-tu-dau-den-cuoi-pnh</guid>
      <description>&lt;h2&gt;
  
  
  Giới thiệu
&lt;/h2&gt;

&lt;p&gt;Hẳn bạn đã từng nghe đến số Palindrome, tức là những số có tính đối xứng khi đọc từ trái qua phải và ngược lại. Nhưng liệu bạn đã bao giờ tự hỏi: làm thế nào để tìm số Palindrome gần nhất với một số bất kỳ? Trong bài viết này, chúng ta sẽ cùng nhau khám phá cách giải quyết bài toán "Tìm Số Palindrome Gần Nhất" bằng cách sử dụng kỹ thuật Binary Search – một phương pháp đầy mạnh mẽ và hiệu quả.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bài Toán Đặt Ra
&lt;/h2&gt;

&lt;p&gt;Cho một chuỗi số nguyên n, nhiệm vụ của bạn là tìm số Palindrome gần nhất với n, nhưng không phải là chính n. Nếu có hai số Palindrome có cùng khoảng cách tới n, bạn cần trả về số nhỏ hơn trong hai số đó.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ví Dụ Minh Họa
&lt;/h2&gt;

&lt;p&gt;Input: n = "123"&lt;/p&gt;

&lt;p&gt;Output: 121&lt;/p&gt;

&lt;p&gt;Input: n = "1"&lt;/p&gt;

&lt;p&gt;Output: 0&lt;/p&gt;

&lt;h2&gt;
  
  
  Tư Duy Giải Quyết
&lt;/h2&gt;

&lt;p&gt;Để giải quyết bài toán này, ta cần tìm ra hai số Palindrome:&lt;/p&gt;

&lt;p&gt;Số Palindrome nhỏ hơn gần nhất với n.&lt;br&gt;
Số Palindrome lớn hơn gần nhất với n.&lt;br&gt;
Sau đó, chúng ta sẽ so sánh khoảng cách giữa n và hai số này để tìm ra số gần nhất.&lt;/p&gt;
&lt;h2&gt;
  
  
  Kỹ Thuật Binary Search
&lt;/h2&gt;

&lt;p&gt;Binary Search (tìm kiếm nhị phân) là một phương pháp giúp thu hẹp phạm vi tìm kiếm một cách nhanh chóng, đặc biệt hữu ích khi chúng ta làm việc với các tập hợp số lớn.&lt;/p&gt;
&lt;h2&gt;
  
  
  Các Bước Thực Hiện
&lt;/h2&gt;

&lt;p&gt;Tìm Số Palindrome Tiếp Theo:&lt;/p&gt;

&lt;p&gt;Khởi tạo khoảng tìm kiếm với biên trái là n + 1 và biên phải là một giá trị cực lớn.&lt;br&gt;
Sử dụng Binary Search để tìm số Palindrome lớn hơn gần nhất với n.&lt;br&gt;
Tìm Số Palindrome Trước Đó:&lt;/p&gt;

&lt;p&gt;Khởi tạo khoảng tìm kiếm với biên trái là 0 và biên phải là n - 1.&lt;br&gt;
Sử dụng Binary Search để tìm số Palindrome nhỏ hơn gần nhất với n.&lt;br&gt;
Giải Thuật Chi Tiết&lt;/p&gt;
&lt;h2&gt;
  
  
  Dưới đây là mô tả chi tiết về các hàm cần thiết để triển khai giải thuật:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;convert(num)&lt;/code&gt;: Hàm này nhận đầu vào là một số nguyên num và tạo ra số Palindrome bằng cách đối xứng hóa nửa đầu của chuỗi số.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;next_palindrome(num)&lt;/code&gt;: Sử dụng Binary Search để tìm số Palindrome lớn hơn gần nhất với num.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prev_palindrome(num)&lt;/code&gt;: Sử dụng Binary Search để tìm số Palindrome nhỏ hơn gần nhất với num.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nearestPalindromic(n)&lt;/code&gt;: Hàm chính của bài toán, trả về số Palindrome gần nhất với n.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Dưới đây là đoạn mã Python hiện thực toàn bộ giải thuật:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def convert(self, num: int) -&amp;gt; int:
        s = str(num)
        n = len(s)
        l, r = (n-1) // 2, n // 2
        s_list = list(s)

        while l&amp;gt;=0:
            s_list[r] = s_list[l]
            r += 1
            l -= 1

        return int("".join(s_list))

    def next_palindrome(self, num: int) -&amp;gt; int:
        left, right = 0, num
        ans = float('inf')

        while left &amp;lt;= right:
            mid = (right-left) // 2 + left
            palin = self.convert(mid)
            if palin &amp;lt; num:
                ans = palin
                left = mid + 1

            else:
                right = mid - 1

        return ans

    def prev_palindrome(self, num: int) -&amp;gt; int:
        left, right = num, int(1e18)
        ans = float('-inf')
        while left &amp;lt;= right:
            mid = (right-left) // 2 + left
            palin = self.convert(mid)
            if palin &amp;gt; num:
                ans = palin
                right = mid - 1

            else:
                left = mid + 1

        return ans

    def nearestPalindromic(self, n: str) -&amp;gt; str:
        num = int(n)
        a = self.next_palindrome(num)
        b = self.prev_palindrome(num)
        if abs(a-num) &amp;lt;= abs(b-num):
            return str(a)

        return str(b)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lời Khuyên Cuối Cùng
&lt;/h2&gt;

&lt;p&gt;Bài toán này không chỉ giúp bạn luyện tập kỹ năng lập trình mà còn nâng cao khả năng tư duy thuật toán. Việc hiểu rõ cách hoạt động của Binary Search và cách ứng dụng nó trong bài toán này sẽ mở ra cho bạn nhiều hướng giải quyết khác nhau trong các bài toán phức tạp khác.&lt;/p&gt;

&lt;p&gt;Hãy tiếp tục luyện tập, viết lại các giải pháp dưới dạng blog hoặc ghi chép, và chia sẻ kiến thức của mình. Đó chính là cách tốt nhất để tiến bộ và trở thành một developer giỏi hơn mỗi ngày.&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dailychallenge</category>
      <category>dingzhang</category>
    </item>
    <item>
      <title>[LDC 19.08.2024] 650. 2 Keys Keyboard - Tối Ưu Tạo ra n Ký Tự 'A'</title>
      <dc:creator>Dinh Truong Phan</dc:creator>
      <pubDate>Mon, 19 Aug 2024 13:45:27 +0000</pubDate>
      <link>https://dev.to/dtruong46me/cach-toi-uu-de-tao-ra-n-ky-tu-a-tren-leetcode-5hk9</link>
      <guid>https://dev.to/dtruong46me/cach-toi-uu-de-tao-ra-n-ky-tu-a-tren-leetcode-5hk9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cách Tối Ưu Để Tạo ra n Ký Tự 'A' trên Leetcode – Đừng Để Bài Toán Này Làm Khó Bạn!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bạn có từng gặp bài toán nào mà chỉ có một ký tự 'A' trên màn hình, và nhiệm vụ của bạn là tạo ra nhiều ký tự 'A' nhất có thể? Nghe có vẻ dễ, nhưng bạn sẽ ngạc nhiên với độ phức tạp ẩn chứa bên trong! Hôm nay, chúng ta sẽ cùng nhau giải mã bài toán này một cách dễ hiểu và tối ưu nhất.&lt;/p&gt;

&lt;h1&gt;
  
  
  Bài Toán - Bắt Đầu Từ Số 0
&lt;/h1&gt;

&lt;p&gt;Bài toán yêu cầu bạn tìm ra số bước tối thiểu để tạo ra n ký tự 'A' từ một ký tự 'A' ban đầu trên màn hình. Bạn chỉ có hai thao tác: Copy All và Paste. Nhưng liệu bạn có thể tìm ra cách tối ưu để đạt được n ký tự chỉ trong vài bước?&lt;/p&gt;

&lt;h1&gt;
  
  
  Phân Tích - Tìm Kiếm Chiến Lược
&lt;/h1&gt;

&lt;p&gt;Trước khi chúng ta lao vào code, hãy thử nghĩ về bài toán này. Nếu bạn muốn có n ký tự 'A', bạn phải bắt đầu từ con số nào? Dĩ nhiên là từ 1. Vậy sau đó thì sao? Bạn cần copy tất cả ký tự hiện có, rồi paste chúng nhiều lần. Nhưng làm thế nào để biết khi nào cần copy, khi nào cần paste?&lt;/p&gt;

&lt;h1&gt;
  
  
  Dynamic Programming - Cứu Tinh Của Những Bài Toán Phức Tạp
&lt;/h1&gt;

&lt;p&gt;Đây chính là nơi mà Dynamic Programming (Quy hoạch động) tỏa sáng. Thay vì xử lý trực tiếp từng bước, chúng ta sẽ xây dựng một bảng (mảng dp) lưu trữ số bước tối thiểu để đạt được từng số lượng ký tự 'A' từ 1 đến n.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ví dụ cụ thể:
&lt;/h1&gt;

&lt;p&gt;Bạn có 1 ký tự 'A' (dp[1] = 0).&lt;br&gt;
Bạn muốn có 2 ký tự? Bạn cần copy và paste (2 bước).&lt;br&gt;
Nhưng nếu bạn muốn có 4 ký tự? Đầu tiên, copy tất cả (1 bước), sau đó paste 3 lần (3 bước). Tổng cộng là 4 bước.&lt;/p&gt;

&lt;h1&gt;
  
  
  Code - Đưa Chiến Lược Thành Hành Động
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Solution:
    def minSteps(self, n: int) -&amp;gt; int:
        dp = [1000 for _ in range(n+1)]  # Khởi tạo giá trị lớn cho dp
        dp[1] = 0  # Chỉ cần 0 bước để có 1 ký tự 'A'

        for i in range(2, n+1):
            for j in range(1, i//2+1):
                if i % j == 0:  # Kiểm tra nếu i chia hết cho j
                    dp[i] = min(dp[i], dp[j] + i//j)  # Cập nhật số bước tối thiểu

        return dp[n]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Giải Thích - Không Chỉ Là Code
&lt;/h1&gt;

&lt;p&gt;Trong đoạn code trên, chúng ta sử dụng mảng dp để lưu trữ số bước tối thiểu cần thiết. Với mỗi số lượng ký tự từ 2 đến n, chúng ta kiểm tra xem liệu nó có thể được tạo ra từ một số lượng ký tự nhỏ hơn bằng cách nhân (copy + paste). Nếu có, chúng ta cập nhật số bước tối thiểu cho dp[i].&lt;/p&gt;

&lt;h1&gt;
  
  
  Kết Quả - Bài Toán Trở Nên Dễ Dàng Hơn
&lt;/h1&gt;

&lt;p&gt;Bằng cách áp dụng quy hoạch động, chúng ta đã biến một bài toán tưởng chừng phức tạp trở nên dễ dàng hơn nhiều. Bây giờ bạn không cần phải lo lắng về việc tìm cách tạo ra n ký tự 'A' trong thời gian tối thiểu nữa!&lt;/p&gt;

&lt;h1&gt;
  
  
  Lời Khuyên Cuối Cùng
&lt;/h1&gt;

&lt;p&gt;Hãy thử áp dụng chiến lược này cho các bài toán khác trên Leetcode và ghi chú lại những gì bạn đã học được. Việc này không chỉ giúp bạn ghi nhớ sâu hơn mà còn tạo cơ hội để bạn tự tin hơn khi đối mặt với các bài toán khó.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Đừng quên! Mỗi khi bạn gặp một bài toán khó, hãy thử phân tích nó một cách cẩn thận và tìm ra chiến lược giải quyết trước khi viết code. Đó chính là cách mà các developer hàng đầu chinh phục Leetcode!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>leetcode</category>
      <category>dailychallenge</category>
      <category>dingzhang</category>
    </item>
    <item>
      <title>Git và Docker: Công Cụ Quan Trọng Trong Phát Triển AI/ML và MLOps</title>
      <dc:creator>Dinh Truong Phan</dc:creator>
      <pubDate>Wed, 22 May 2024 15:47:49 +0000</pubDate>
      <link>https://dev.to/dtruong46me/git-va-docker-cong-cu-quan-trong-trong-phat-trien-aiml-va-mlops-l2p</link>
      <guid>https://dev.to/dtruong46me/git-va-docker-cong-cu-quan-trong-trong-phat-trien-aiml-va-mlops-l2p</guid>
      <description>&lt;h2&gt;
  
  
  Quản Lý Phiên Bản Với Git
&lt;/h2&gt;

&lt;p&gt;Trong phát triển phần mềm, việc theo dõi và quản lý các thay đổi là rất quan trọng. Đây là lúc mà Version Control (hệ thống quản lý phiên bản) trở thành công cụ không thể thiếu. Git là hệ thống quản lý phiên bản phân tán phổ biến nhất hiện nay, giúp chúng ta dễ dàng theo dõi lịch sử thay đổi, phân nhánh và hợp nhất mã nguồn, cũng như làm việc nhóm hiệu quả.&lt;/p&gt;

&lt;p&gt;Lợi ích của Git:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Theo dõi lịch sử thay đổi: Mọi thay đổi trong mã nguồn đều được lưu lại, giúp chúng ta biết ai đã thực hiện thay đổi gì và khi nào.&lt;/li&gt;
&lt;li&gt;Phân nhánh và hợp nhất: Cho phép tạo ra các nhánh (branch) để phát triển các tính năng mới hoặc sửa lỗi mà không ảnh hưởng đến mã nguồn chính. Khi hoàn tất, các nhánh này có thể được hợp nhất (merge) vào mã nguồn chính.&lt;/li&gt;
&lt;li&gt;Làm việc nhóm hiệu quả: Cho phép nhiều lập trình viên làm việc trên cùng một dự án mà không gây xung đột.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ví dụ:&lt;/p&gt;

&lt;p&gt;Khi làm việc trên một dự án lớn với nhiều thành viên, Git giúp mỗi người làm việc trên nhánh riêng của họ và sau đó hợp nhất lại mà không gây ảnh hưởng đến công việc của người khác. Điều này đặc biệt quan trọng trong các dự án AI/ML, nơi mà các mô hình và mã nguồn thường xuyên được cập nhật và thử nghiệm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker: Tối Ưu Hóa Triển Khai Ứng Dụng
&lt;/h2&gt;

&lt;p&gt;Docker là công cụ mạnh mẽ giúp chúng ta triển khai ứng dụng trong các container. Các container này sử dụng chung kernel của hệ điều hành chủ, dẫn đến việc khởi động nhanh hơn và sử dụng tài nguyên hiệu quả hơn so với các máy ảo (virtual machines).&lt;/p&gt;

&lt;p&gt;Khác biệt giữa Docker và máy ảo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker: Chạy các ứng dụng trong các container, khởi động nhanh hơn và sử dụng tài nguyên hiệu quả hơn.&lt;/li&gt;
&lt;li&gt;Virtual Machines (VMs): Chạy một hệ điều hành đầy đủ trên một phần cứng ảo hóa, sử dụng tài nguyên nhiều hơn và thời gian khởi động lâu hơn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ví dụ:&lt;/p&gt;

&lt;p&gt;Nếu bạn cần khởi chạy nhiều ứng dụng nhỏ, Docker là lựa chọn tốt hơn vì nó nhẹ và nhanh. Nếu bạn cần môi trường hoàn toàn cách ly với hệ điều hành khác, VM là lựa chọn thích hợp.&lt;/p&gt;

&lt;p&gt;Khái niệm về Docker images và containers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker image: Là một mẫu không thay đổi (immutable template) chứa mọi thứ cần thiết để chạy một ứng dụng, bao gồm mã, thư viện, và cài đặt.&lt;/li&gt;
&lt;li&gt;Docker container: Là một instance đang chạy của một Docker image. Nó chứa mọi thứ từ image và thêm các thay đổi tại thời điểm chạy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ví dụ:&lt;/p&gt;

&lt;p&gt;Một Docker image có thể là một ứng dụng web được cấu hình sẵn. Khi bạn khởi chạy image này, bạn tạo ra một container đang chạy phiên bản ứng dụng web đó.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ứng Dụng Thực Tiễn Của Docker và Git
&lt;/h2&gt;

&lt;p&gt;Lợi ích của việc sử dụng Git:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quản lý mã nguồn hiệu quả: Theo dõi và quản lý các thay đổi trong mã nguồn dễ dàng.&lt;/li&gt;
&lt;li&gt;Làm việc nhóm: Hỗ trợ nhiều lập trình viên làm việc trên cùng một dự án mà không gặp xung đột.&lt;/li&gt;
&lt;li&gt;Phân nhánh và hợp nhất: Cho phép phát triển và thử nghiệm các tính năng mới một cách an toàn.&lt;/li&gt;
&lt;li&gt;Khả năng quay lại: Dễ dàng quay lại phiên bản trước đó nếu cần.
Mục đích của tệp .gitignore:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;.gitignore là tệp chứa danh sách các tệp và thư mục mà Git nên bỏ qua, không theo dõi hoặc không thêm vào kho lưu trữ. Điều này giúp tránh việc lưu trữ những tệp không cần thiết hoặc nhạy cảm.&lt;/p&gt;

&lt;p&gt;Ví dụ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plaintext
Copy code
node_modules/
*.log
.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Các dòng này sẽ làm cho Git bỏ qua thư mục node_modules, các tệp log, và tệp .env.&lt;/p&gt;

&lt;p&gt;Tích Hợp Docker Với Quy Trình CI/CD&lt;/p&gt;

&lt;p&gt;Docker có thể được tích hợp vào quy trình CI/CD để tự động hóa việc xây dựng, kiểm thử, và triển khai ứng dụng. Các bước bao gồm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Xây dựng image Docker trong pipeline CI: Mỗi khi có thay đổi trong mã nguồn, image mới được tạo ra.&lt;/li&gt;
&lt;li&gt;Kiểm thử container: Chạy các kiểm thử trong container để đảm bảo ứng dụng hoạt động đúng.&lt;/li&gt;
&lt;li&gt;Triển khai container: Đẩy image mới lên registry và triển khai container từ image này.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ví dụ:&lt;/p&gt;

&lt;p&gt;Sử dụng Jenkins, bạn có thể thiết lập các bước để tự động xây dựng và đẩy Docker image lên Docker Hub mỗi khi mã nguồn được cập nhật.&lt;/p&gt;

&lt;p&gt;Quản Lý Docker Containers Trong Sản Xuất&lt;/p&gt;

&lt;p&gt;Một số thực hành tốt nhất để quản lý Docker containers trong môi trường sản xuất:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sử dụng images nhỏ gọn: Giảm kích thước image để tăng tốc độ triển khai và khởi động container.&lt;/li&gt;
&lt;li&gt;Bảo mật: Chạy container với quyền hạn tối thiểu, sử dụng images chính thức và thường xuyên cập nhật để vá lỗ hổng bảo mật.&lt;/li&gt;
&lt;li&gt;Giám sát và ghi log: Theo dõi hiệu suất và ghi log container để phát hiện và khắc phục sự cố kịp thời.&lt;/li&gt;
&lt;li&gt;Sao lưu dữ liệu: Đảm bảo dữ liệu quan trọng được sao lưu định kỳ.&lt;/li&gt;
&lt;li&gt;Tự động hóa: Sử dụng các công cụ như Kubernetes để tự động quản lý và điều phối container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ví dụ:&lt;/p&gt;

&lt;p&gt;Sử dụng Kubernetes để tự động điều phối và quản lý các container, đảm bảo khả năng mở rộng và khắc phục sự cố một cách tự động.&lt;/p&gt;

&lt;p&gt;Kết Luận&lt;br&gt;
Git và Docker là hai công cụ mạnh mẽ không thể thiếu trong phát triển AI/ML và MLOps. Git giúp quản lý mã nguồn và làm việc nhóm hiệu quả, trong khi Docker tối ưu hóa quá trình triển khai ứng dụng. Việc sử dụng đúng cách các công cụ này sẽ giúp dự án của bạn đạt được hiệu suất và độ tin cậy cao nhất.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>[PapEx] Human Eval Dataset &amp; pass@k metric</title>
      <dc:creator>Dinh Truong Phan</dc:creator>
      <pubDate>Tue, 14 May 2024 17:51:59 +0000</pubDate>
      <link>https://dev.to/dtruong46me/papex-human-eval-dataset-passk-metric-4ie3</link>
      <guid>https://dev.to/dtruong46me/papex-human-eval-dataset-passk-metric-4ie3</guid>
      <description>&lt;p&gt;Nếu các bạn đang làm trong lĩnh vực AI/Machine Learning, chắc hẳn các bạn sẽ biết đến các metric thông dụng để đánh giá độ chính xác của mô hình như accuracy, precision, recall,... Tuy nhiên, khi đánh giá cho bài toán Code Generation thì các metrics trên  không phải là tối ưu và chúng ta cần chọn 1 metric khác để đánh giá. Không phải BLEU, ROUGE mà là pass@k metric.&lt;/p&gt;

&lt;p&gt;Nguồn: &lt;a href="https://arxiv.org/pdf/2107.03374"&gt;https://arxiv.org/pdf/2107.03374&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trước tiên, pass@k hiểu đơn giản là xem xét trong những đoạn sample codes/problem mà con LLM generate ra, có bao nhiêu đoạn là pass test cases. Mục tiêu là xác định xem xác suất mà "ít nhất 1 trong &lt;code&gt;k&lt;/code&gt; đoạn codes" là đúng. &lt;/p&gt;

&lt;p&gt;Lấy 1 ví dụ đơn giản như này, chúng ta đã có trained LLM, và chúng ta cần đánh giá con LLM này trên 10 problems (tất nhiên tập dataset sẽ có input-text, test-cases). Trước hết bạn cho con LLM này generate ra mỗi 8 sample codes/problem (tổng cộng là 10x8=80 đoạn codes), sau đó xác định xem xác suất có ít nhất 1 đoạn code đúng trong 8 đoạn code được sinh ra.&lt;/p&gt;

&lt;p&gt;Mới đầu có 1 ông (Kulal et al. cho model generate &lt;code&gt;k&lt;/code&gt; sample codes/problem, nhưng phương pháp này bị high variance, hiểu đơn giản là không hiệu quả lắm). Về sau, người ta cải tiến hơn đó là thay vì generate &lt;code&gt;k&lt;/code&gt; samples, người ta sẽ cho model generate ra &lt;code&gt;n&lt;/code&gt; samples/problem (&lt;code&gt;n&amp;gt;=k&lt;/code&gt;, trong paper người ta lấy &lt;code&gt;n=200&lt;/code&gt;, &lt;code&gt;k&amp;lt;=100&lt;/code&gt;) và tính số lượng correct sample &lt;code&gt;c&lt;/code&gt; mà pass tất cả các unit tests.&lt;/p&gt;

&lt;p&gt;Tôi sẽ chứng minh công thức pass@k metric ở đoạn này&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Objective: probability mà ít nhất 1 đoạn code đúng trong k đoạn codes (given `n` là số lượng đoạn code sinh ra, `c` là số lượng đoạn code đúng)
-&amp;gt; Nghịch đảo bài toán: Tính xác suất trong `k` đoạn code thì tất cả đều sai

C(k,n-c) / C(k,n)

trong đó 
+ C(k,n-c): tổng số k đoạn code được chọn trong (n-c) incorrect sample codes
+ C(k,n): tổng số k đoạn code được chọn trong n đoạn code

Suy ra để có ít nhất 1 đoạn code là đúng trong k đoạn code:

pass@k = 1 - C(k,n-c) / C(k,n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Còn có 1 cách giải thích khác và công thức khác của pass@k (trong phần Appendix của paper)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pass@k = 1 - (1 - pass@1)^k 

Trong đó: 
+ pass@1 = 1 - C(1,n-c) / C(1,n) = 1 - (n-c)/n = c/n
+ 1-pass@1: xác suất mà đoạn code được chọn là sai
+ k: có tất cả k samples -&amp;gt; xác suất để tất cả k samples đều sai (không pass test cases) là (1-pass@1)^k 
-&amp;gt; nghịch đảo lấy 1 trừ là ra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Về HumanEval Dataset:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Có tất cả 164 problems&lt;/li&gt;
&lt;li&gt;Trung bình 7.7 test cases / problem&lt;/li&gt;
&lt;li&gt;Khái niệm "Sandbox": để executing generated programs (Tức là khi model generate ra những đoạn code, thì cần phải chạy xem có pass test cases không -&amp;gt; chạy ở "Sandbox")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementation:&lt;br&gt;
Về flow của việc evaluatation: Bạn đã có model và cần đánh giá task code generation trên tập HumanEval. Trước tiên bạn phải cho model generate ra &lt;code&gt;n x 164&lt;/code&gt; đoạn codes (n là số lượng đoạn code sinh ra mỗi problem, và có tất cả 164 problems) sau đó mới evaluate code ở "Sandbox". Hiểu đơn giản là sẽ có 2 phases: Generate code -&amp;gt; Evaluate Code&lt;/p&gt;

&lt;p&gt;Tại sao lại làm như vậy, nếu bạn có suy nghĩ giống tôi và lúc implement tôi cũng thắc mắc như thế này: Tại sao không vừa generate vừa evaluate, tức là mỗi problem mà model generate ra, thì sẽ evaluate luôn thay vì generate tất cả 200x164=32800 đoạn code sau đó mới evaluate, làm vậy thì lâu bỏ m* ra :))). Tại thư viện người ta viết vậy chứ giờ sửa thế nào được. &lt;/p&gt;

&lt;p&gt;Bạn đọc có thể tham khảo cách implement trên README.md ở link sau: &lt;a href="https://github.com/openai/human-eval"&gt;https://github.com/openai/human-eval&lt;/a&gt;&lt;br&gt;
Bạn có thể sử dụng GPU để generate code nhanh hơn (Kiểu như 2 con GPU chạy song song sẽ sinh code nhanh hơn mỗi con CPU)&lt;/p&gt;

&lt;p&gt;Tôi thấy cách implement cũng khá đơn giản và tôi sẽ gửi lại các bạn phần mà tôi evaluate mô hình CodeT5, CodeT5+ của nhà Salesforce bằng tập HumanEval với metric pass@k ở dưới phần comment.&lt;/p&gt;

&lt;p&gt;Vậy thôi&lt;/p&gt;

</description>
      <category>paperexplained</category>
    </item>
    <item>
      <title>Lời khuyên khi làm Project cùng nhau</title>
      <dc:creator>Dinh Truong Phan</dc:creator>
      <pubDate>Tue, 14 Nov 2023 15:27:57 +0000</pubDate>
      <link>https://dev.to/dtruong46me/loi-khuyen-khi-lam-project-cung-nhau-2kaj</link>
      <guid>https://dev.to/dtruong46me/loi-khuyen-khi-lam-project-cung-nhau-2kaj</guid>
      <description>&lt;p&gt;Mình đang là sinh viên năm 3, đã từng làm tương đối nhiều project môn học. Và mình đã đúc rút được rất nhiều kinh nghiệm qua những lần thất bại khi làm việc nhóm.&lt;/p&gt;

&lt;p&gt;Việc đầu tiên mình khuyên các bạn là phải tuân thủ quy trình của một project. Ở đây, nhóm trưởng phải là người hiểu rõ quy trình, và hướng mọi người tuân thủ quy trình (có thể là những cuộc họp, phân chia công việc,...). Trong quy trình xây dựng 1 project (hoặc phần mềm,web,...) gồm có 4-5 bước:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;B1: Làm rõ vấn đề&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Trước khi đánh trận thì ít nhất các bạn cũng phải biết địch là ai, mình là ai chứ đúng không? Địch ở đây là project là gì, phải làm gì, input, output là gì, thậm chí thầy cô là ai (đùa đấy, chả ai nói thầy cô là địch cả :&amp;gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;B2: Thiết kế&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Sau khi xác định được vấn đề, bài toán rồi thì bắt tay vào thiết kế chương trình thôi. Đa số các bạn sinh viên chưa có kinh nghiệm (thường thì các bạn sẽ được làm project từ năm 2, năm 3 nên cũng không có kinh nghiệm nhiều lắm) nên việc thiết kế chương trình hoàn hảo từ A đến Z thì khá là khó, nên thường bước này các bạn thường bỏ qua. Các bạn thường bắt tay vào code luôn, innovar luôn xong mới thiết kế. Mình khuyên các bạn là không lên làm như vậy nha. Hãy thiết kế trước, sơ qua cũng được thì mới sắp xếp, dễ chia việc, với cả dễ dàng bảo trì trong suốt quá trình làm project. Thiết kế đơn giản như các classes, methods, attributes, thậm chí database, các quan hệ,... Sau đó chia việc và quản lý code có phải dễ hơn đúng không nào&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;B3: Code&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Bước này chắc mình không phải giải thích nhiều, các bạn biết bài toán, nhiệm vụ của mình rồi thì innovar thôi. Chắc các bạn IT thích nhất là phần này, vì được gõ máy tính. Có gì không hiểu thì hỏi nhóm trưởng, nhóm trưởng không rep thì hỏi Chat GPT, Claude, Bard,... Nói chung là bước này là bước chính nhưng mình ít thấy các bạn ngồi thiết kế, xây dựng bài toán là mấy. Thực ra mấy ông thiết kế, xây dựng bài toán, quản lý nhóm mới thực sự đỉnh nha (không phải nói tôi đâu, thực ra tôi thiết kế và code hết chứ cái team mình tạ quá. Đùa đấy tùy từng project thôi nhưng chưa project nào là mình không gồng gánh cái team này cả)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;B4: Test&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Lại đa số các bạn bỏ qua bước này, mình cũng thỉnh thoảng thế. Tại vì các bạn toàn để đến gần deadline mới làm (thường 1-2 tuần cuối gì đấy) nên có thời gian qué đâu mà test với cả deploy :))). Thực ra viết test cases cũng đơn giản mà chill mà. Thông thường các classes, methods sẽ do nhóm trưởng yêu cầu các bạn return về 1 giá trị nào đó, nên các bạn sẽ không thể chạy được classes đó trực tiếp. Nên các bạn sẽ phải tạo 1 file khác để test classes và methods đó (chuẩn ra là như thế). Hiểu ý mình không (chắc chắn không hiểu rồi, không hiểu thì để lại comment nha). Việc test lại chương trình sẽ khiến project của bạn trông chuyên nghiệp hơn rất nhiều&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;B5: Deploy&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Thông thường project trên trường sẽ không thấy bước này mấy, deploy web lại phải mua server các thứ (tiền đâu ra? ai bỏ tiền? deploy xong để làm gì? cho đẹp à, đi khoe à?...). Hay deploy app, lại render ra mấy file .exe xong làm gì có ai tải, thầy cô bận trăm công nghìn việc ai mà rảnh tải hay clone project của ông về rồi chạy, dở à. Nên gần như 90% sẽ không phải deploy nhưng mà trên lab, đồ án cuối khóa thì cần nha, các bạn cũng nên học để cho đỡ bỡ ngỡ&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(Hết Phần 1 nha, Phần 2 mình sẽ giới thiệu công cụ quản lý code - Git khi làm project nhóm)&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
