23 / 24 · Thực hành
Dự án tổng kết: đường suy luận nhỏ và báo cáo
Giữ K=9,bốn đầu ra và một chu kỳ thêm mỗi đầu ra nhưng dùng ba PE. Tổng chu kỳ mô hình và mức sử dụng ô chỉ tính MAC là gì?
Bài học miễn phí. Đăng ký để lưu tiến độ học tập.
Mục tiêu và tiêu chí chấp nhận
Giữ model.mjs của bài trước,tạo capstone-lab.mjs cạnh nó và chạy node capstone-lab.mjs. Nối một lớp tích chập,bias,lượng tử hóa lại,ReLU và gộp cực đại. Báo giá trị riêng với chi phí. Đây không phải bộ phân loại hay engine huấn luyện đầy đủ. Có thể xem thủ công tệp qua quy trình tệp Digital Design Studio đã cài được hỗ trợ; chưa xác lập thực thi trong DDS.
Hoàn thành khi bộ tích lũy tích chập trực tiếp và patch-dot khớp,dữ liệu trung gian/đầu ra khớp,và báo cáo gồm kích thước,MAC,chu kỳ giả định,mức sử dụng ô và byte tensor duy nhất. Thêm một dữ liệu đổi đầu vào được tính tay độc lập. Giữ lệnh,phiên bản tệp và giả định cùng log. Điều tra so sánh thất bại thay vì chỉ sửa giá trị kỳ vọng.
Tính tham chiếu
Đầu vào là 4×4 với giá trị 1 đến 16. Kernel [1,0,−1;1,0,−1;1,0,−1] trừ mẫu phải khỏi mẫu trái mỗi hàng. Mỗi hàng cho −2, nên mọi cửa sổ có tổng −6. Bias tám cho bốn bộ tích lũy bằng hai. Hệ số 0.5 và điểm 0 bằng 0 tạo mã một. ReLU giữ nó và gộp 2×2 cho [1]. Cũng giữ dữ liệu biên bất đối xứng; đầu ra bằng nhau có thể che lỗi thứ tự.
Kích thước [M,Ho,Wo] là [1,2,2]. Đếm 36 MAC, gồm số hạng trọng số 0. Với hai PE một MAC chia phép rút gọn mỗi đầu ra, giả định năm chu kỳ MAC cộng một kết hợp/ghi mỗi đầu ra, không chồng lấp hay dừng. Tổng mô hình là 24 chu kỳ. Mức sử dụng ô chỉ tính MAC là 36/(4×5×2)=90%. Đây không phải độ trễ thiết bị đo được.
Tensor int8 duy nhất dùng đầu vào 16,trọng số 9,đầu ra tích chập 4 byte,cộng bias bốn byte. Đầu ra gộp dùng một byte. Lưu lượng thực có thể gồm tải lại và tổng riêng. Thang sx=sw=1, sy=2 giải thích hệ số 0.5.
Đổi bias về 0 dự đoán bộ tích lũy −6,mã −3,kích hoạt 0 và gộp 0. Chỉ đổi đầu vào đầu tiên từ một thành hai cho bộ tích lũy đầu ba,trường hợp giữa 1.5 làm tròn thành hai,ba đầu ra còn lại một và gộp hai. Kiểm tra các thay đổi riêng. Nhiều PE hơn hoặc bỏ trọng số 0 cần lịch rõ ràng mới trong khi giữ giá trị.
Tệp có thể chạy
import assert from 'node:assert/strict';
import {conv2d, im2col, dot, requantize, maxPool2x2} from './model.mjs';
const x = [Array.from({length: 4}, (_, r) => Array.from({length: 4}, (_, c) => r * 4 + c + 1))];
const kernel = [[1, 0, -1], [1, 0, -1], [1, 0, -1]];
const weights = [[kernel]], bias = [8];
const reference = conv2d(x, weights, {bias});
const flattenedWeights = kernel.flat();
const rows = im2col(x, 3, 3);
const accumulators = rows.map(row => dot(row, flattenedWeights) + bias[0]);
assert.deepEqual(accumulators, reference[0].flat());
assert.deepEqual(accumulators, [2, 2, 2, 2]);
const activated = reference[0].map(row => row.map(v => Math.max(0, requantize(v, 0.5))));
const pooled = maxPool2x2(activated);
assert.deepEqual(activated, [[1, 1], [1, 1]]);
assert.deepEqual(pooled, [[1]]);
// Cycle estimate with explicit assumptions: all MAC operands local, no stalls,
// one output at a time, K=9, two single-MAC PEs, no overlap with output write.
const macs = rows.length * flattenedWeights.length;
const peCount = 2, macCyclesPerOutput = Math.ceil(flattenedWeights.length / peCount);
const modelCycles = rows.length * (macCyclesPerOutput + 1);
const usefulSlots = macs, scheduledSlots = rows.length * macCyclesPerOutput * peCount;
assert.equal(macs, 36);
assert.equal(modelCycles, 24);
assert.equal(usefulSlots / scheduledSlots, 0.9);
const report = {shape:[1, 2, 2], accumulators, activated, pooled, macs, peCount,
modelCycles, macSlotUtilization:usefulSlots / scheduledSlots,
uniqueInputBytes:16, weightBytes:9, outputBytes:4, biasBytes:4,
scope:'Software reference and schedule estimate only; no synthesis or DDS run'};
console.log(JSON.stringify(report, null, 2));Dự án tổng kết RTL: tích chập số nguyên
Các tệp đính kèm cnn_window3x3.sv và cnn_conv3x3.sv nối cửa sổ tới chín tích 8×8 có dấu,tổng/bias 24 bit có dấu,chia hai gần nhất chọn chẵn,bão hòa int8,ReLU và cực đại 2×2. Hình học theo quy ước trước:4×4,một kênh,3×3 không đệm. Thang đầu vào/trọng số là một,thang đầu ra hai,mọi điểm 0 bằng 0. Kernel mặc định [1,0,−1;1,0,−1;1,0,−1],bias tám. Tham số kernel có thể đổi;kiểm tra lại giới hạn tổng 24 bit.
So riêng out_acc,out_code và out_activation,cùng out_row/out_col và lần truyền đầu ra được chấp nhận. done lên sau khi kết quả thứ tư được chấp nhận;lúc đó pooled hợp lệ. Mười sáu đầu vào đã chấp nhận không ngụ ý hoàn thành. RTL này dùng chín tích song song và hai tầng có thanh ghi,thay vì ước tính hai PE,24 chu kỳ trước. Tần số/công suất cần bằng chứng tổng hợp hoặc thiết bị.
Chạy testbench tự kiểm tra dùng chung:
iverilog -g2012 -s tb_cnn_stream -o cnn-sim cnn_window3x3.sv cnn_conv3x3.sv tb_cnn_stream.sv
vvp cnn-simBộ tích lũy mặc định là hai,mã/kích hoạt một,đầu ra gộp một. Kiểm tra gồm biên có dấu,bão hòa,trường hợp giữa dương/âm,kernel có dấu dày,tạm dừng và reset. Xác minh PASS frames=6 windows=24 outputs=24 kernels=2 trong log thực. Đổi đầu vào đầu thành hai:tổng đầu ba làm tròn thành mã hai,pooled thành hai. Rồi chọn kernel có dấu khác,tính tay cửa sổ đầu,cập nhật hàm hệ số độc lập và chạy lại mọi dữ liệu thử. Không sao chép kết quả DUT vào mô hình chuẩn.
Tự thử
Giữ K=9,bốn đầu ra và một chu kỳ thêm mỗi đầu ra nhưng dùng ba PE. Tổng chu kỳ mô hình và mức sử dụng ô chỉ tính MAC là gì?
Đọc giải thích
Mỗi đầu ra mất ba chu kỳ MAC cộng một thêm, nên tổng mười sáu. Cả 36 ô MAC đều hữu ích, cho 100%. Cùng tần số,cấp dữ liệu và chi phí kết hợp vẫn cần bằng chứng triển khai riêng.