1 điểm bởi GN⁺ 2024-10-17 | 2 bình luận | Chia sẻ qua WhatsApp
  • Khi chạy benchmark NPU trên SoC dựa trên Qualcomm Arm của Microsoft Surface Pro 11th Edition, thông lượng đo được thấp hơn nhiều so với hiệu năng tăng tốc mà Windows AI PC quảng bá
  • Bài kiểm thử được cấu hình để chạy phép toán MatMul lớn, tương tự các layer tốn chi phí cao trong những mô hình họ transformer, bằng Onnx Runtime và Qualcomm QNN execution provider
  • Trong kết quả ví dụ, CPU đạt 821 Gigaops/s, còn NPU đạt 225 Gigaops/s ở cấu hình lượng tử hóa với đầu vào/đầu ra float và 573 Gigaops/s ở cấu hình áp dụng cả đầu vào/đầu ra 8-bit
  • Mức 573 Gigaops/s của NPU chỉ bằng khoảng 1,3% so với 45 Teraops/s trong tài liệu marketing của Microsoft Surface Pro 11th Edition; khi chạy cùng mô hình trên Nvidia Geforce RTX 4080 Laptop GPU, kết quả là 3,2 ms và 2.160 Gigaops/s
  • Kết quả hiện tại tính đến ngày 2/10/2024; dù có thể kỳ vọng độ trễ sẽ giảm nhờ cải tiến ở tầng phần mềm, framework và driver, trong benchmark hiện tại CPU nhanh hơn NPU

Mục đích benchmark NPU Qualcomm trên Surface

  • Microsoft bán tablet Surface trang bị SoC dựa trên Qualcomm Arm dưới dạng Windows AI PC, quảng bá rằng máy có thể chạy các mô hình machine learning nhanh hơn và hiệu quả hơn
  • Useful Sensors có đánh giá tích cực về phần cứng Qualcomm và NPU, đồng thời đã đầu tư thời gian và tài nguyên để port ứng dụng bên thứ ba của mình sang nền tảng này
  • Do không có nhiều ví dụ mã hoặc benchmark cho thấy nhà phát triển bên ngoài có thể đạt kết quả nhanh như thế nào, họ công bố hiệu năng quan sát thực tế dưới dạng một dự án độc lập nhỏ
  • Hiệu năng đo được thấp hơn nhiều so với kỳ vọng; vì từng có trải nghiệm rằng cùng phần cứng hoạt động hiệu quả trên các nền tảng khác như Android, họ vẫn để ngỏ khả năng cải thiện trong tương lai thông qua thay đổi ở ứng dụng, framework và driver

Môi trường chạy và ràng buộc cài đặt

  • Bài kiểm thử dùng script Python trên Windows
    • Tính đến ngày 2/10/2024, Python trên Microsoft Store không hỗ trợ kiến trúc Arm, nên không phù hợp để chạy các package cần thiết để truy cập Qualcomm NPU
    • Kết quả sử dụng bộ cài Python 3.11.9 Arm64
  • Chưa có package Onnx dựng sẵn cho Windows on Arm, nên cần CMake và trình biên dịch Visual Studio
    • Cài CMake bằng winget install cmake
    • Visual Studio dùng Visual Studio Community Edition; khi cài đặt chọn workload Desktop C++ Development
  • Cài các package Python trong thư mục repository bằng py -m pip install -r requirements.txt
    • Nhánh Onnx là phiên bản đã backport bản sửa lỗi biên dịch cho launcher py chính thức vào Onnx 1.16
    • Qualcomm Onnx Runtime phát sinh lỗi Unsupported model IR version với Onnx mới nhất, nên sử dụng tổ hợp này
    • Package Qualcomm Onnx Runtime dùng bản nightly build

Chạy benchmark và diễn giải đầu ra

  • Chạy benchmark bằng py benchmark_matmul.py
  • Onnx Runtime xuất khá nhiều log trong lần chạy ban đầu
    • Ví dụ có thông báo cpuinfo rằng không nhận diện được model chip Snapdragon(R) X 12-core X1E80100 @ 3.40 GHz
    • Log ở giai đoạn hoàn tất graph và giai đoạn hoàn thành cũng được in ra
  • Kết quả benchmark thực tế hiển thị ở cuối
    • NPU quantized compute, float I/O accuracy difference is 0.0100
    • NPU quantized compute and I/O accuracy difference is 0.0060
    • CPU took 8.42ms, 821,141,860,688 ops per second
    • NPU (quantized compute, float I/O) took 30.63ms, 225,667,671,183 ops per second
    • NPU (quantized compute and I/O) took 12.05ms, 573,475,650,364 ops per second
  • Hai dòng đầu cho thấy độ chênh lệch chính xác để kiểm tra kết quả số giữa CPU và NPU có khớp nhau không
  • Ba dòng cuối cho thấy thời gian wall-clock để chạy mô hình từ đầu đến cuối, cùng số phép toán mỗi giây tính từ độ trễ đó

Mô hình được đo và cách lượng tử hóa

  • Benchmark được thiết kế để tái hiện 6 phép nhân ma trận lớn tương tự các layer tốn thời gian trong mô hình transformer như OpenAI Whisper
    • Hình dạng đầu vào là (6, 1500, 256) X (6, 256, 1500)
    • Hình dạng kết quả là (6, 1500, 1500)
    • Mô hình gồm một node MatMul duy nhất với 2 đầu vào và 1 đầu ra
  • Mô hình được tạo tức thời bằng framework mô hình Onnx rồi chuyển cho Onnx Runtime
  • Mô hình chuẩn là phiên bản float thuần túy và chỉ chạy trên CPU
  • Để chạy hiệu quả, NPU chủ yếu cần mô hình lượng tử hóa; float16 chỉ được hỗ trợ hạn chế
  • Cách tiếp cận NPU đầu tiên dùng phương thức ORT chính thức quantize_static()
    • Để thuận tiện, tensor đầu vào và đầu ra vẫn giữ dạng float 32-bit
    • Runtime thực hiện chuyển đổi ở đầu và cuối graph, phần tính toán còn lại chạy ở 8-bit
  • Với cấu hình này, các phép chuyển đổi của NPU rất chậm; trong npu_quant_profile.csv, chuyển đổi chiếm hơn 75% tổng thời gian
  • Cách tiếp cận thứ hai tạo bằng chương trình một graph mô hình tương đương có đầu vào và đầu ra 8-bit
    • Cách quantized compute and I/O này thường nhanh hơn khoảng 3 lần so với phiên bản float I/O
    • Trong profiling, phần lớn thời gian được dùng cho phép nhân ma trận như kỳ vọng

Các biến số được cân nhắc khi đo hiệu năng

  • Để xét liệu có compute bound hay không, hình dạng ma trận được đặt gần vuông hơn
    • Các mô hình transformer hiện đại, khác với các mô hình convolution cũ, dựa trên những phép nhân ma trận lớn
    • Khi layer gần với phép nhân ma trận-vector hơn, khả năng tái sử dụng trọng số giảm và việc nạp giá trị từ DRAM có thể trở thành nút thắt cổ chai
    • Chiều k của ma trận tiny Whisper gốc là 64, nhưng trong benchmark này được tăng lên 256 để mở rộng dư địa tối ưu hóa SIMD
  • Thiết lập nguồn điện được đặt theo hướng tăng hiệu năng
    • Các thiết lập năng lượng của Windows được cố gắng đặt về Best Performance
    • Benchmark được chạy khi tablet đang cắm nguồn
    • Tùy chọn phiên htp_performance_mode của Qualcomm Onnx Runtime được đặt là sustained_high_performance, mức cho độ trễ tổng thể thấp nhất trong thử nghiệm
  • Cấu trúc mô hình được giới hạn ở một phép nhân ma trận duy nhất để dễ diễn giải
    • Dù cũng có thể dùng nhiều layer, convolution hoặc trọng số tĩnh, họ chọn một MatMul duy nhất với đầu vào động để phản ánh cấu trúc transformer được dùng rộng rãi trong LLM và các mô hình hiện đại
  • Vẫn có khả năng cấu hình sai
    • Sử dụng lượng tử hóa unsigned 8-bit và các phần tử qdq trong graph
    • Dù đã cố làm theo best practice trong tài liệu, có thể cấu hình này đã đi lệch khỏi fast path của driver hoặc triển khai accelerator
  • Các lựa chọn API để truy cập tăng tốc AI trên Windows cũng được xem xét
    • DirectML dường như chỉ hỗ trợ truy cập GPU
    • OpenVino dường như không chạy trên phần cứng Arm này
    • Việc dùng trực tiếp Qualcomm QNN SDK cũng cho kết quả hiệu năng tương tự
    • TensorFlow Lite không hỗ trợ Windows for Arm
    • Trong khảo sát và thử nghiệm này, Onnx có vẻ là framework phù hợp nhất để đạt hiệu năng tăng tốc NPU, vì được cả Microsoft lẫn Qualcomm hỗ trợ

Diễn giải kết quả

  • Kết quả tính đến ngày 2/10/2024 và được đo trên Microsoft Surface Pro 11th Edition
    • SoC là Snapdragon(R) X 12-core X1E80100 @ 3.40 GHz
  • Ngay cả khi loại trừ chuyển đổi float, kết quả NPU vẫn chậm hơn CPU
    • Xét từ góc độ accelerator, đây không phải là điều lý tưởng
    • Tuy vậy, không loại trừ khả năng NPU có lợi thế về hiệu quả năng lượng hoặc hiệu năng duy trì
  • Hiệu năng NPU cao nhất đo được, 573 billion ops/s, bằng 1,3% so với 45 trillion ops/s trong tài liệu marketing Microsoft Surface Pro 11th Edition
  • Khi chạy cùng mô hình trên Nvidia Geforce RTX 4080 Laptop GPU, mất 3,2 ms
    • Tương ứng với 2.160 billion ops/s
    • Thông lượng này cao gần gấp 4 lần so với kết quả đo NPU của Surface

2 bình luận

 
bungker 2024-10-18

Tôi cứ nghĩ Ryzen NPU nhanh hơn CPU một chút, nhưng đọc xong thì hứng thú với Snapdragon tụt hẳn.

 
GN⁺ 2024-10-17
Ý kiến trên Hacker News
  • Nhìn vào kết quả thì có vẻ nhìn chung việc tận dụng tài nguyên tính toán chưa tốt. CPU 8,4ms, GPU 3,2ms thì chênh lệch quá nhỏ; ở đây có lẽ người ta đã kỳ vọng mức chênh 10–20 lần
    Nguyên nhân có thể là onnxruntime. Có vẻ một số hãng phần cứng chỉ đưa ra đơn vị tính toán nhưng phần hỗ trợ tử tế thì chưa đi kèm; cần xem tình hình sẽ thay đổi nhanh đến đâu
    Ngoài ra, nhiều người hiểu nhầm mục đích của NPU là “tốc độ”, nhưng điểm cốt lõi là tiêu thụ điện thấp. Nếu nhắm tới tốc độ thì phải loại bỏ nút thắt bộ nhớ, và rốt cuộc sẽ phải thiết kế ASIC có bộ nhớ riêng. NPU trong phần lớn thiết bị được gắn vào SoC quanh CPU để offload các phép tính AI
    Sẽ rất thú vị nếu chạy benchmark này trong vòng lặp vô hạn trên cả ba thiết bị CPU/NPU/GPU rồi đo mức tiêu thụ điện. Tôi dự đoán NPU sẽ thấp nhất và cũng có số phép tính trên mỗi watt tốt nhất

    • Tôi nghi ngờ lý do thật sự của NPU có khi là marketing. Có thể là kiểu “NVDA được định giá 3,3 nghìn tỷ USD cơ à, vậy hãy nhét thứ gì đó AI vào sản phẩm của mình”
    • NPU cũng có mục đích lớn là offload. Tùy trường hợp sử dụng, CPU và GPU có thể đang bận làm việc khác, nên NPU trở thành băng thông bổ sung có thể dùng mà không tranh giành lẫn nhau
      Ví dụ với bộ lọc ảnh AI, nhiều khả năng GPU đang render phần xem trước, còn CPU bận xử lý UI và đầu vào của người dùng
    • Đây chính là hào lũy của Nvidia. Gần như mọi thứ đều có kernel tối ưu cho CUDA, và trong một số trường hợp thì có cỡ Apple Accelerate
      Apple Accelerate từng là con đường gần như duy nhất để truy cập các đơn vị ma trận CPU trước M4 và NPU. Nếu muốn dùng thứ khác, bạn phải sẵn sàng gửi patch cho framework machine learning đã chọn, hoặc tự viết mã huấn luyện và suy luận
    • Tôi đang dùng onnxruntime để làm ứng dụng bằng C thuần, và hiệu năng tốt hơn khá nhiều so với một ứng dụng tương tự viết bằng Python. Vẫn còn rất nhiều cải thiện hiệu năng có thể đạt được
      Rốt cuộc Python cũng gọi C, nhưng việc bao nhiêu hiệu năng biến mất là điều khá thú vị
    • Có vẻ thời gian chưa được đo đúng, và “thời gian” thường được marketing cũng hay khác với thứ mọi người nghĩ là giá trị đo. Dù vậy, các con số marketing đôi khi lại dễ so sánh
      Nếu dùng GPU, cần cân nhắc liệu tác vụ bất đồng bộ có được tính vào phần đo thời gian hay không
      Nếu ngây thơ dùng time.time(), CPU chỉ ghi lại thời gian; model(input.cuda()).cuda() sẽ đưa dữ liệu vào bộ nhớ GPU và bắt đầu tính toán, nhưng vì là bất đồng bộ nên thời điểm kết thúc có thể được ghi lại bất kể kết quả thực sự đã sẵn sàng hay chưa
      Đây là hành vi khó kỳ vọng nếu không hiểu hệ thống và phần cứng. Không chỉ Python, đa số ngôn ngữ đều được thiết kế để có thể biên dịch thành dạng tối ưu hơn đoạn mã bạn viết, và vì không có khóa nên không chặn tác vụ CPU
      Muốn đo tác vụ GPU thực sự thì nên xem bộ đếm thời gian sự kiện CUDA. Trong PyTorch có thể dùng torch.cuda.Event(enable_timing=True)
      Ngoài ra kích thước và định dạng bộ nhớ cũng phức tạp. Benchmark này dùng định dạng bất lợi cho NPU. NPU và GPU thường muốn channels last, nên [1,1500,1500,6] mới đúng hơn [1,6,1500,1500]
      1500 và 6 cũng là những con số không thuận, không tốt cho NPU; xét việc các thiết bị này vẫn còn mới, tổn thất hiệu năng có thể khá lớn
      Tôi đã viết chi tiết hơn tại https://news.ycombinator.com/item?id=41864828
  • Các NPU kiểu này chiếm diện tích silicon đáng kể, nên nếu rốt cuộc chúng không được dùng mấy thì sẽ rất đáng tiếc. Tôi không tìm được phân tích khuôn die của Snapdragon X tách riêng phần NPU, nhưng phía AMD với mục tiêu tương tự khoảng 50 TOPS có thể xem ở đây, và nó chiếm diện tích khoảng bằng 3 nhân CPU hiệu năng cao
    https://www.techpowerup.com/325035/amd-strix-point-silicon-p...

    • Tôi mong cơn sốt LLM kết thúc để một mức độ lẽ thường và hiệu quả nào đó quay trở lại. Cá nhân tôi không có việc gì cần dùng phần cứng bổ sung này, “GenAI” không giúp ích gì cho tôi và cũng không hỗ trợ các tác vụ liên quan đến công việc
      Tệ hơn nữa, có vẻ đa số mọi người cũng không cần nó, và các khảo sát gần đây thậm chí cho thấy thái độ phản cảm trước sự xâm nhập của AI chiếm ưu thế. Không nên bắt trả thêm tiền cho những thứ như vậy; chúng phải là tùy chọn
      Làm vậy thì doanh số sẽ cho thấy có ít người muốn trả “phụ phí AI” đến mức nào, và sẽ làm rõ thứ này bị thổi phồng và không cần thiết ra sao
    • Chip hiện đại phải để lại một tỷ lệ nhất định của die dưới dạng dark silicon. Nếu không, nó sẽ nóng chảy hoặc bị throttle đến mức vô dụng. Những thành phần như vậy cũng được tính vào tỷ lệ đó
      Vì thế mục đích của các bộ phận này là được dùng, nhưng không được dùng quá nhiều
      Thay vì NPU, đúng là có thể dùng số transistor và diện tích die đó cho nhiều mục đích khác, nhưng họ có lẽ sẽ không thêm nhiều nhân CPU hiệu năng cao hơn. Làm vậy mật độ công suất sẽ quá cao, gây ra vấn đề nhiệt khó giải quyết nếu không throttle lâu dài
      [1] https://en.wikipedia.org/wiki/Dark_silicon
    • Tôi cũng nghĩ vậy. Hiện tại muốn mua hệ thống có NPU thì vẫn phải chủ động tìm nên tôi chưa có, nhưng có lẽ sau này nó sẽ được đưa vào mặc định
      Với những người không chạy model, nó trông như một sự lãng phí, và tôi tò mò có cách nào dùng nó cho mục đích khác không
    • Snapdragon X vẫn là 12 nhân, và là cấu trúc đồng nhất với tất cả các nhân giống nhau. Strix Point cũng 12 nhân nhưng cấu hình 4+8, và các nhân “nhỏ” cũng không hy sinh hiệu năng đến mức gần như mất ý nghĩa tồn tại như các nhân nhỏ trong thiết kế ARM
      Phần mềm tiêu dùng không mở rộng tới mức đó, nên có phân bổ thêm transistor cho CPU thì cũng làm được gì, tôi tự hỏi
      Điều này cũng giống phần nào lý do Apple đưa nhiều video engine vào SoC. Với ngân sách transistor có thể chấp nhận được thì không có nhiều chỗ khác đáng để dùng. Cải thiện hiệu năng đơn luồng không còn chỉ bị giới hạn bởi số lượng transistor nữa, còn phần mềm thì không giỏi đa luồng
  • Tôi từng nghĩ mục đích của những thiết bị này không phải là chạy nhanh, mà là chạy các mô hình nhỏ với mức điện năng rất thấp. Tôi dùng một laptop AMD đời mới có NPU; khi bật hiệu ứng video được cho là chạy trên NPU thì mức tiêu thụ điện không thay đổi, nhưng dùng Nvidia Studio Effects thì điện năng tăng lên
    NPU có vẻ dành cho các mô hình được tối ưu hóa rất mạnh để làm những tác vụ nhỏ như căn chỉnh ánh nhìn, làm mờ nền, mô hình tự động hiệu chỉnh, phiên âm, OCR. Đặc biệt trên Windows, tôi hiểu là nó chạy OCR toàn màn hình và embedding để tìm kiếm cho tính năng rewind

    • Nhất là nếu thiết bị đó là Xilinx FPGA thì càng đúng. Thứ được gắn vào Ryzen di động mới nhất còn có hiệu năng tốt hơn 5 lần
      AMD dạo này đang làm rất tốt, nhưng có vẻ họ không quảng bá rầm rộ. Cái này đặc biệt thú vị: https://lore.kernel.org/lkml/DM6PR12MB3993D5ECA50B27682AEBE1...
      Sửa: không phải FPGA. Hôm nay mới biết
    • Tôi cũng hiểu như vậy. Điểm cốt lõi là điện năng thấp và độ trễ thấp
      Có thể kiểm chứng bằng cách đánh giá các mô hình CoreML trên macOS. ANE mất khoảng một nửa thời gian so với GPU, còn GPU mất khoảng một nửa thời gian so với CPU. Tỉ lệ thực tế tùy theo mô hình
    • Tôi cho rằng điện năng thấp đồng nghĩa với token rẻ hơn, dẫn đến việc sử dụng dễ chi trả hơn và bền vững hơn. Lợi ích tổng thể cho người tiêu dùng nằm ở đây. GPU ngốn nhiều điện có vẻ phù hợp hơn cho nghiên cứu, thương mại và doanh nghiệp
      Con chip có thể đe dọa Nvidia sẽ là chip và bộ nhớ đủ rẻ để chạy các mô hình đủ tốt trên thiết bị cá nhân như smartphone
      Nếu công chúng nói chung đồng ý rằng LLM hữu ích và sẵn sàng trả thêm một chút phí premium cho giá thiết bị, tôi nghĩ tương lai của công nghệ này về bản chất là các mô hình cá nhân cung cấp quyền riêng tư
      Lượng thông tin cá nhân mà mọi người đổ vào những nơi như ChatGPT thật đáng kinh ngạc. Nhìn Reddit thì thấy nhiều người nghiện các ứng dụng bạn gái AI ảo thường giao cả những sở thích đen tối nhất, những lời thú nhận dễ tổn thương, thậm chí cả các cuộc trò chuyện có thể cấu thành tội phạm cho những công ty ứng dụng vô danh
      Google cũng nói rõ rằng nếu bật lịch sử Gemini, họ có thể xem xét nội dung cuộc trò chuyện
      Các dự đoán token phức tạp cần mô hình lớn hơn thì có thể hỏi LLM trên đám mây, nhưng với người tiêu dùng, quyền riêng tư nhất thiết phải được bảo đảm
      Với trợ lý cá nhân hằng ngày, trò chuyện và tìm kiếm thông tin, tôi không nghĩ cần đến suy luận tối tân hay những LLM kiểu trình diễn kỹ xảo
    • Dựa trên những gì tôi nghe được khi Pixel ra mắt nhận dạng giọng nói trên thiết bị, và kết quả tôi chạy các tác vụ ONNX trên Apple Neural Engine và CPU sau khi rời Google, tôi nghĩ nhận định này đúng
      Tuy nhiên, tôi hơi nghi ngờ các kết luận cụ thể của bài viết. Đó là ONNX của Qualcomm, và có thể đã cũ. Phía Android từng chê khá nhiều về kỹ thuật phần mềm của Qualcomm
      Dù vậy hướng đi là đúng. Phần lớn các tuyên bố tăng tốc AI trên phần cứng tiêu dùng gần như luôn là thổi phồng, ngoại lệ là A) dùng phần mềm 1P hoặc B) có ai đó nội bộ 1P thật sự muốn bạn tận dụng tính năng đó
    • Đúng. Tuy nhiên có lẽ bạn sẽ không muốn lập trình những thiết bị này bằng Python. Đặc biệt vì đây là thiết bị mới, nhiều tối ưu có thể chưa được port tốt nên khó kỳ vọng hiệu năng cao
      Ngay cả dùng thứ như TensorRT cũng không nhanh bằng tự viết từ đầu, và đó cũng là lý do Nvidia投入 rất nhiều nhân lực. Dù vậy nó vẫn tiến khá gần và giảm đáng kể thời gian viết
      Các thiết bị kiểu này nhìn chung được tối ưu cho những tác vụ tương tự lặp đi lặp lại. Vì vậy tôi nghĩ một phần thông tin thu thập ở đây có thể không chính xác
      Tôi chưa trực tiếp dùng các chip NPU này, nhưng khó tin hoàn toàn vào phần đo thời gian. Phần đo thời gian CUDA ở cuối nhiều khả năng không được đo đúng trong mã. Đo thời gian khó hơn tưởng tượng
      Số phép tính được quảng cáo chỉ tính các phép tính thực hiện trực tiếp trên NPU, trong khi bài gốc có thể đã tính cả công việc CPU vào phép đo NPU và GPU. Tài liệu có công cụ benchmark nên có lẽ nên dùng cách tương tự, và tôi cũng tò mò độ phân tán sau khi warm-up sẽ như thế nào
      Định dạng dữ liệu dường như cũng sai. Ở đây cần channels last. Tài liệu cũng xác nhận điều này
      Con số 1500 cũng hơi lạ, nên có thể phát sinh thêm sai sót. Với 1536, 2048, 256 hoặc các giá trị nhỏ hơn, kết quả có thể khác. Mô hình thực tế không xử lý ảnh ở độ phân giải đầy đủ, và nếu tối ưu kiến trúc cho mô hình thì thông tin về shape sẽ trở nên quan trọng. Trong machine learning, tối ưu shape khá quan trọng
      Xem nhanh tài liệu thì phần cấu hình cũng có vẻ không phù hợp. “Model Workflow” nói rằng dữ liệu mong muốn là số nguyên 8 bit hoặc số thực dấu phẩy động 16 bit, nhưng số thực dấu phẩy động cũng có nhiều loại. bfloat của PyTorch không giống torch.half hay torch.float16
      Mixed precision đến nay vẫn là một chủ đề dễ gây nhầm lẫn, nên nếu có vấn đề kiểu này thì đáng để xem xét kỹ. Tôi không khuyến nghị chỉ chạy quy trình lượng tử hóa tiêu chuẩn rồi kết thúc. Nó là điểm khởi đầu tốt, nhưng nếu chưa “đủ tốt” thì không nên dừng ở đó
      Dù vậy tôi không nghĩ các kết quả này vô dụng. Chỉ là chúng cần được cải thiện. Những việc như thế này phức tạp hơn tưởng tượng, và phần lớn là vì công nghệ còn mới, các chi tiết vẫn đang được hoàn thiện
      Khi so sánh với CPU hoặc GPU, đặc biệt là CUDA, cần nhớ rằng đã có hàng trăm nghìn giờ-người được投入, và ngay cả các thư viện cấp cao như Python cũng có ít nhất hàng chục nghìn giờ-người. Những thiết bị này vẫn chưa thật sự sẵn sàng để người dùng trung bình dùng ngay ở mức trừu tượng ngôn ngữ họ ưa thích, nhưng nếu sẵn sàng làm việc gần phần cứng hơn thì chúng khá hữu ích
      Để đo tác vụ bất đồng bộ của GPU trong PyTorch, nên dùng CUDA event và torch.cuda.synchronize() thay vì dùng bộ đếm thời gian CPU bọc quanh đầu ra của mô hình
      [1] https://www.thonking.ai/p/what-shapes-do-matrix-multiplicati...
  • Để triển khai mô hình lên NPU, cần khá nhiều tối ưu hóa dựa trên profiling. Nếu lấy một mô hình chạy tốt trên CPU rồi đưa sang NPU mà không tối ưu cho NPU, kết quả thường sẽ gây thất vọng

    • Cái hay của CPU là nó có thể xử lý gần như bất kỳ đoạn mã lộn xộn nào với tốc độ hợp lý
    • Mỗi lần nói chuyện với những người làm việc với các thứ như IREE hay OpenXLA, tôi đều có ấn tượng rằng việc hiểu và sử dụng các compiler và runtime đó tự thân đã là một nghề
  • Phần mô tả của kho GitHub hữu ích hơn blog rất nhiều
    Khi chạy phép nhân ma trận int8 bằng onnx, hiệu năng khoảng 0.6TF
    https://github.com/usefulsensors/qc_npu_benchmark

  • Họ nói đã làm cho ma trận đầu vào gần vuông hơn để có thể tiling và tái sử dụng, nhưng cũng không có gì ngạc nhiên nếu khá nhiều tối ưu hóa khả thi đã không được đưa vào Onnx
    Có vẻ Qualcomm không cho truy cập trực tiếp vào NPU, mà kỳ vọng người dùng chuyển đổi mô hình qua framework rồi đưa vào. Theo kinh nghiệm của tôi, các công cụ chuyển đổi nói chung không tốt lắm nên bỏ lỡ nhiều tối ưu hóa
    Vì vậy có thể không phải “NPU kém”, mà là “công cụ chuyển đổi kém”. Tôi sẽ đợi đến khi có thể truy cập trực tiếp, và không tin các công cụ chuyển đổi
    Tôi nghĩ NPU phù hợp với các mô hình machine learning rất nhỏ và xấp xỉ hàm rất nhanh. Đó là mục đích sử dụng tôi nhắm tới. LLM hiện đang rất nóng, nhưng có vô số tác vụ chuyên biệt mà mô hình nhỏ thực sự hữu ích

    • Bạn có thể nêu ví dụ về các tác vụ chuyên biệt mà mô hình nhỏ hữu ích không? Nếu có thể, tôi muốn ví dụ trong đó ngay cả mô hình nhỏ cũng được chạy liên tục đủ để nằm trong cache, và có giá trị với đủ nhiều người dùng để biện minh cho việc chiếm cache đó
      Không phải tôi nói là không có, nhưng thật lòng tôi không biết đó là gì nên muốn tìm hiểu
    • Tôi cũng định nói điều này. Tôi chưa dùng Elite X, nhưng ở các thiết bị thế hệ trước, chủ yếu là 865, compute DSP đóng vai trò accelerator và NPU nhỏ hơn nhiều cần những thứ như cấu hình rất cụ thể, biên dịch bằng toolchain riêng, giao tiếp RPC
      Hy vọng NPU của Elite X đã dễ truy cập hơn nhờ Copilot+, nhưng ý chính là không thể dễ kiểu “chạy mô hình đa dụng rồi nó sẽ tự dịch chuyển thần kỳ sang NPU” được
  • RTX 4080 lẽ ra phải đạt khoảng 40 TFLOPS, nhưng ở đây chỉ báo cáo 216 tỷ phép toán mỗi giây. Mức này khiến tôi nghĩ cần xem lại benchmark
    Rất có khả năng đã có lỗi nghiêm trọng trong cách đo FLOPS. CPU thắng NPU là điều có thể, nhưng để so sánh đúng thì cần benchmark nhiều phép nhân ma trận mà không có đồng bộ hóa ứng dụng

    • Đó chỉ là một phần. Chỉ lướt qua tài liệu cũng thấy suy luận trên CPU cũng không được thực hiện theo cách có thể so sánh được
  • Benchmark là phép nhân ma trận dạng (6, 1500, 256) X (6, 256, 1500), trong thế giới AI thì kích thước này không lớn lắm. Với ma trận lớn hơn nhiều, khoảng cách sẽ còn lớn hơn
    Ví dụ ngay cả Llama 3.1 8B, một trong những mô hình nhỏ, cũng có phép nhân ma trận như (batch, 14336, 4096) x (batch, 4096, 14336)
    Tôi cho rằng benchmark này chưa đủ thực tế

  • Tôi đã chạy qprof, profiler NPU của Qualcomm, trên benchmark này. Kết quả profiling cho thấy công việc được phân bổ cho vector core, chứ không phải tensor core, nơi cung cấp phần lớn sức mạnh tính toán của NPU
    Tính sơ bộ thì HMX có vẻ mạnh hơn HVX khoảng 30 lần
    Khối lượng công việc tương đối nhỏ nên không tận dụng đủ năng lực phần cứng do overhead của lượng tử hóa/giải lượng tử hóa đầu vào/đầu ra và ánh xạ NCHW-NHCW. Padding trọng số và đầu vào lên bội số của 64 cũng sẽ giúp hiệu năng
    Đồ thị profiling: https://imgur.com/a/2OKR93e
    Hiệu năng tính toán HVX ước tính là 4 * 2 * 1.43 * 1024 / 8 = 1.46TOPS với int8. Trong đó 4 là số vector core, 2 là số phép toán mỗi chu kỳ, 1.43GHz là tần số HVX, 1024bit là độ rộng thanh ghi vector, và 8bit là độ chính xác

    • Định dạng công thức bị sai, phải là 4 * 2 * 1.43 * 1024 / 8
  • Tiêu đề thực sự của bài nên là “Benchmarking Qualcomm's NPU on the Microsoft Surface Tablet”
    Đây không phải là bài viết về NPU nói chung, mà là xem xét một NPU cụ thể với một benchmark cụ thể và một tổ hợp thư viện/framework cụ thể. Vì vậy về cơ bản nó chẳng chứng minh được gì