### Install Example Requirements Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Install dependencies required for running example tests. This is typically needed only once. ```bash pip install -r examples/requirements.txt # only needed the first time ``` -------------------------------- ### Run Example Tests with Pytest Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Execute tests for the examples using pytest. Ensure example requirements are installed first. ```bash python -m pytest -n auto --dist=loadfile -s -v ./examples/ ``` -------------------------------- ### Run Example Tests with Unittest Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Execute tests for the examples using the standard unittest module. This command discovers and runs tests from the 'examples' directory. ```bash python -m unittest discover -s examples -t examples -v ``` -------------------------------- ### Install Dependencies and EdgeBERT Source: https://github.com/harvard-acc/edgebert/blob/main/sw/README.md Follow these commands to set up the Python environment, install necessary libraries, and install the EdgeBERT transformers package. ```bash conda create --name test-edge python=3.7 source activate test-edge pip install torch pip install tensorboard pip install -U scikit-learn cd EdgeBERT/transformers python setup.py install ``` -------------------------------- ### Install Dependencies Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Installs the required version of urllib3. ```python !pip install urllib3==1.25.4 ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Install the project in editable mode with development dependencies. This command ensures all necessary packages for development are available in your virtual environment. ```bash $ pip install -e ".[dev]" ``` -------------------------------- ### Install EdgeBERT Transformers Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Navigates to the transformers directory and installs the package. ```python %cd ./EdgeBERT/EdgeBERT/transformers/ !python setup.py install %cd ../../.. ``` -------------------------------- ### Install EdgeBERT Dependencies Source: https://context7.com/harvard-acc/edgebert/llms.txt Commands to set up the conda environment and install required Python packages and the EdgeBERT library. ```bash # Create conda environment conda create --name edgebert python=3.7 source activate edgebert # Install dependencies pip install torch pip install tensorboard pip install -U scikit-learn # Install EdgeBERT transformers library cd sw/EdgeBERT/transformers python setup.py install ``` -------------------------------- ### Install Unreleased isort Version Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Install a specific unreleased version of 'isort' to avoid a known bug. This is a temporary workaround until the bug is fixed in a stable release. ```bash $ pip install -U git+git://github.com/timothycrosley/isort.git@e63ae06ec7d70b06df9e528357650281a3d3ec22#egg=isort ``` -------------------------------- ### Get Average Predict Layer Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Calculates the average prediction layer using entropy prediction without early exit before. ```python %%shell ENTROPIES="0.09 0.16 0.28" for ENTROPY in $ENTROPIES; do echo $ENTROPY python ../examples/masked_run_highway_glue.py --model_type albert \ --model_name_or_path ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --task_name SST-2 \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size=1 \ --overwrite_output_dir \ --output_dir ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --plot_data_dir ./plotting/ \ --early_exit_entropy $ENTROPY \ --eval_highway \ --entropy_predictor \ --predict_layer 1 \ --lookup_table_file ./sst2_lookup_table_opt.csv \ --no_ee_before \ --overwrite_cache done ``` -------------------------------- ### Download GLUE Data Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Clones the GLUE baselines repository and downloads the necessary datasets. ```python !git clone https://github.com/nyu-mll/GLUE-baselines.git !python GLUE-baselines/download_glue_data.py ``` -------------------------------- ### Build and Run EdgeBERT Simulation Source: https://github.com/harvard-acc/edgebert/blob/main/hw/README.md Commands to clone the repository and execute the C++ compilation and simulation of the Top-level accelerator. ```bash git clone --recursive https://github.com/harvard-acc/EdgeBERT.git cd EdgeBERT/hw/cmod/TopAccel make make run ``` -------------------------------- ### Run Library Tests with Unittest Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Execute all library tests using the standard unittest module. This command discovers and runs tests from the 'tests' directory. ```bash python -m unittest discover -s tests -t . -v ``` -------------------------------- ### Clone and Build EdgeBERT Hardware Accelerator Source: https://context7.com/harvard-acc/edgebert/llms.txt Clones the EdgeBERT repository and builds the SystemC simulation for the hardware accelerator. Ensure tool paths are configured in the Makefile. ```bash # Clone repository with submodules (NVIDIA MatchLib) git clone --recursive https://github.com/harvard-acc/EdgeBERT.git cd EdgeBERT/hw/cmod/TopAccel # Configure tool paths in cmod_Makefile # Set BOOST_HOME, SYSTEMC_HOME, CATAPULT_HOME # Build the accelerator simulation make # Run simulation make run ``` -------------------------------- ### Train Teacher Model Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Trains the teacher model using the run_glue script. ```python !python ../examples/run_glue.py \ --model_type albert \ --model_name_or_path albert-base-v2 \ --task_name SST-2 \ --do_train \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size 1 \ --per_gpu_train_batch_size 32 \ --learning_rate 3e-5 \ --num_train_epochs 3 \ --save_steps 0 \ --seed 42 \ --output_dir ./saved_models/albert-base/SST-2/teacher \ --overwrite_cache \ --overwrite_output_dir ``` -------------------------------- ### Add and Commit Changes Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Stage your modified files using 'git add' and then commit them locally with 'git commit'. Remember to write clear and informative commit messages. ```bash $ git add modified_file.py $ git commit ``` -------------------------------- ### Train EdgeBERT with Distillation and Pruning Source: https://context7.com/harvard-acc/edgebert/llms.txt Execute the training pipeline for the EdgeBERT model using knowledge distillation, adaptive attention, and magnitude pruning. ```bash #!/bin/bash export CUDA_VISIBLE_DEVICES=0 python examples/masked_run_highway_glue.py \ --model_type masked_albert \ --model_name_or_path albert-base-v2 \ --task_name SST-2 \ --do_train \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size 1 \ --per_gpu_train_batch_size 64 \ --learning_rate 3e-5 \ --num_train_epochs 30 \ --overwrite_output_dir \ --seed 42 \ --output_dir ./saved_models/masked_albert/SST-2/two_stage_pruned_0.5 \ --plot_data_dir ./plotting/ \ --save_steps 0 \ --overwrite_cache \ --eval_after_first_stage \ --adaptive \ --adaptive_span_ramp 256 \ --max_span 512 \ --warmup_steps 1000 \ --mask_scores_learning_rate 1e-2 \ --initial_threshold 1 \ --final_threshold 0.5 \ --initial_warmup 2 \ --final_warmup 3 \ --pruning_method magnitude \ --mask_init constant \ --mask_scale 0. \ --fxp_and_prune \ --prune_percentile 60 \ --teacher_type albert_teacher \ --teacher_name_or_path ./saved_models/albert-base/SST-2/teacher \ --alpha_ce 0.1 \ --alpha_distil 0.9 ``` -------------------------------- ### Check Code Quality with Flake8 Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Run 'flake8' to check for coding mistakes and style issues. While CI also performs these checks, running it locally helps catch errors early. ```bash $ make quality ``` -------------------------------- ### Run Test Suite Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Execute the project's test suite to ensure your changes have not introduced regressions. This command verifies the overall stability of the codebase. ```bash $ make test ``` -------------------------------- ### Load Dataset with NumPy Source: https://github.com/harvard-acc/edgebert/blob/main/sw/Entropy_LUT/entropypredictor.ipynb Loads training and evaluation datasets from specified text files using NumPy's loadtxt function. Assumes data is comma-separated. ```python #load dataset fn2 = "dataset_sst2_eval.txt" fn = "dataset_sst2_train.txt" nparr2 = np.loadtxt(fn2, delimiter=",") nparr = np.loadtxt(fn, delimiter=",") ``` -------------------------------- ### Format Code with Black and isort Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Format your code changes using 'black' and 'isort' to maintain consistent code style across the project. This command should be run before committing your changes. ```bash $ make style ``` -------------------------------- ### Implement Weight Binarization Classes Source: https://context7.com/harvard-acc/edgebert/llms.txt Defines MagnitudeBinarizer for pruning based on absolute value and TopKBinarizer for movement pruning during training. ```python from torch import autograd class MagnitudeBinarizer(object): """ Magnitude Binarizer - prunes weights below threshold based on absolute value. Keeps the k% highest magnitude weights. """ @staticmethod def apply(inputs: torch.tensor, threshold: float): mask = inputs.clone() _, idx = inputs.abs().flatten().sort(descending=True) j = int(threshold * inputs.numel()) flat_out = mask.flatten() flat_out[idx[j:]] = 0 flat_out[idx[:j]] = 1 return mask class TopKBinarizer(autograd.Function): """ Top-k Binarizer - keeps top k% of weights by score value. Used for movement pruning during training. """ @staticmethod def forward(ctx, inputs: torch.tensor, threshold: float): mask = inputs.clone() _, idx = inputs.flatten().sort(descending=True) j = int(threshold * inputs.numel()) flat_out = mask.flatten() flat_out[idx[j:]] = 0 flat_out[idx[:j]] = 1 return mask ``` -------------------------------- ### Create a New Development Branch Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Always create a new branch for your development changes. Do not work directly on the 'master' branch to keep your contributions organized and prevent conflicts. ```bash $ git checkout -b a-descriptive-name-for-my-changes ``` -------------------------------- ### Evaluate Model with Entropy Prediction Source: https://context7.com/harvard-acc/edgebert/llms.txt Uses a lookup table to predict exit layers based on early-layer entropy for DVFS-aware decision making. ```bash #!/bin/bash export CUDA_VISIBLE_DEVICES=0 ENTROPIES="0.09 0.16 0.28" for ENTROPY in $ENTROPIES; do echo "Testing with entropy prediction, threshold: $ENTROPY" python examples/masked_run_highway_glue.py \ --model_type albert \ --model_name_or_path ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --task_name SST-2 \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size 1 \ --overwrite_output_dir \ --output_dir ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --plot_data_dir ./plotting/ \ --early_exit_entropy $ENTROPY \ --eval_highway \ --entropy_predictor \ --predict_layer 1 \ --lookup_table_file ./sst2_lookup_table_opt.csv \ --overwrite_cache done ``` -------------------------------- ### Gather environment information for bug reports Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Use this snippet to collect OS, Python, PyTorch, and TensorFlow versions when reporting bugs. ```python import platform; print("Platform", platform.platform()) import sys; print("Python", sys.version) import torch; print("PyTorch", torch.__version__) import tensorflow; print("Tensorflow", tensorflow.__version__) ``` -------------------------------- ### Train Teacher Model Source: https://context7.com/harvard-acc/edgebert/llms.txt Train a baseline ALBERT teacher model on the SST-2 task to generate soft labels for distillation. ```bash #!/bin/bash export CUDA_VISIBLE_DEVICES=0 python examples/run_glue.py \ --model_type albert \ --model_name_or_path albert-base-v2 \ --task_name SST-2 \ --do_train \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size 1 \ --per_gpu_train_batch_size 32 \ --learning_rate 3e-5 \ --num_train_epochs 3 \ --save_steps 0 \ --seed 42 \ --output_dir ./saved_models/albert-base/SST-2/teacher \ --overwrite_cache \ --overwrite_output_dir ``` -------------------------------- ### Enpy Hardware Entropy Calculator Module Source: https://context7.com/harvard-acc/edgebert/llms.txt Implements the Enpy module for hardware entropy calculation. It includes state machine logic for finding maximum values, computing sums, and evaluating entropy for early exit decisions. ```cpp // Enpy.h - Hardware entropy calculator SC_MODULE(Enpy) { public: sc_in_clk clk; sc_in rst; // Configuration inputs Connections::In start; Connections::In enpy_config; Connections::In act_rsp; // Activation from memory // Outputs Connections::Out enpy_status; // 2=above threshold, 3=below Connections::Out enpy_val_out; Connections::Out done; // State machine states enum FSM { IDLE, FINDMAX, FINDMAX2, RSUM, RSUMb, EVAL, NEXT }; void EnpyRun() { Reset(); while(1) { switch (state) { case FINDMAX: // Request activation vector from memory mask_rd_req.Push(mask_reg); break; case FINDMAX2: // Find maximum value for numerical stability act_reg = act_rsp.Pop(); Adpfloat2Fixed(act_reg, x_vector, adpbias_act1); UpdateMax(x_vector); break; case RSUM: // Compute sum(exp(x-max)) and sum(x*exp(x-max)) for (int i = 0; i < N; i++) { exp_vector_max[i] = exp_vector[i] - maximum_value; } Exponential(exp_vector_max, exp_vector_max); sum_exp += tmp_sum; sum_xexp += tmp_xsum; break; case EVAL: // Compute entropy: log(sum_exp) + max - sum_xexp/sum_exp LogN(sum_exp, log_tmp); tmp_div = sum_xexp / sum_exp; enpy_result = log_tmp + maximum_value - tmp_div; // Compare with threshold if (enpy_result <= enpy_threshold) enpy_status.Push(3); // Exit early else enpy_status.Push(2); // Continue break; } wait(); } } }; ``` -------------------------------- ### Run Library Tests with Pytest Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Execute all library tests using pytest. This command enables parallel execution and verbose output. ```bash python -m pytest -n auto --dist=loadfile -s -v ./tests/ ``` -------------------------------- ### Set Working Directory Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Changes the current working directory to the scripts folder. ```python %cd ./EdgeBERT/EdgeBERT/scripts/ ``` -------------------------------- ### Import Libraries for TensorFlow and NumPy Source: https://github.com/harvard-acc/edgebert/blob/main/sw/Entropy_LUT/entropypredictor.ipynb Imports necessary libraries for numerical operations and deep learning model building. ```python import tensorflow as tf import numpy as np from keras.models import Sequential from keras.layers import Dense from matplotlib.pyplot import plot ``` -------------------------------- ### Train Entropy Prediction Lookup Table Source: https://context7.com/harvard-acc/edgebert/llms.txt Python script for training an entropy prediction lookup table using provided datasets. This table maps early-layer entropy values to predicted entropy for DVFS decisions. ```python # Training entropy prediction lookup table (entropypredictor.ipynb) import numpy as np import pandas as pd from sklearn.linear_model import LinearRegression # Load entropy datasets collected during evaluation train_data = np.loadtxt('dataset_sst2_train.txt') eval_data = np.loadtxt('dataset_sst2_eval.txt') # Format: [layer1_entropy, layer2_entropy, ..., layerN_entropy] ``` -------------------------------- ### Clone Repository and Set Upstream Remote Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Clone your forked repository and add the base repository as a remote named 'upstream'. This is essential for keeping your local copy synchronized with the main project. ```bash $ git clone git@github.com:/transformers.git $ cd transformers $ git remote add upstream https://github.com/huggingface/transformers.git ``` -------------------------------- ### Evaluate Entropy Prediction Performance Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Evaluates the model performance using entropy prediction and a lookup table. ```python %%shell ENTROPIES="0.09 0.16 0.28" for ENTROPY in $ENTROPIES; do echo $ENTROPY python ../examples/masked_run_highway_glue.py --model_type albert \ --model_name_or_path ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --task_name SST-2 \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size=1 \ --overwrite_output_dir \ --output_dir ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --plot_data_dir ./plotting/ \ --early_exit_entropy $ENTROPY \ --eval_highway \ --entropy_predictor \ --predict_layer 1 \ --lookup_table_file ./sst2_lookup_table_opt.csv \ --overwrite_cache done ``` -------------------------------- ### Data Splitting and Feature Extraction Source: https://github.com/harvard-acc/edgebert/blob/main/sw/Entropy_LUT/entropypredictor.ipynb Splits the loaded dataset into training and testing sets, and extracts features based on whether to average entropies or use a specific layer's entropy. The `start_layer` variable determines the split point. ```python #split 80/20 #whether to average entropies up to start_layer or just use entropy at start layer avg = 0 #layer after which you make entropy prediction start_layer = 6 #indexed 0-11 test = nparr2[:,:11] train = nparr[:,:11] if avg: (x_train, y_train) = (train[:,:start_layer], train[:,start_layer+1:]) (x_test, y_test) = (test[:,:start_layer], test[:,start_layer+1:]) x_train = np.mean(x_train, axis=-1) x_test = np.mean(x_test, axis=-1) else: (x_train, y_train) = (train[:,start_layer], train[:,start_layer+1:]) (x_test, y_test) = (test[:,start_layer], test[:,start_layer+1:]) ``` -------------------------------- ### Generate and Save Lookup Table Source: https://github.com/harvard-acc/edgebert/blob/main/sw/Entropy_LUT/entropypredictor.ipynb Creates a lookup table by predicting values for a range of inputs using the trained model. The table is then saved to a CSV file after setting negative values to zero. ```python #produce lookup table table = np.zeros((100, 11-start_layer)) for i in range(0,100): xval = i*0.01; yval = model.predict(np.array([xval]), batch_size=1) table[i,0] = xval table[i,1:] = yval[0] threshold_indices = table < 0 table[threshold_indices] = 0 np.savetxt("sst2_lookup_table_opt.csv", table, delimiter=",") ``` -------------------------------- ### Sync Local Code with Upstream Repository Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Fetch changes from the upstream repository and rebase your local branch onto the latest master. This helps to resolve potential conflicts before pushing. ```bash $ git fetch upstream $ git rebase upstream/master ``` -------------------------------- ### Evaluate Model with Entropy-Based Early Exit Source: https://context7.com/harvard-acc/edgebert/llms.txt Runs evaluation on a highway model using specified entropy thresholds to trigger early exits. ```bash #!/bin/bash export CUDA_VISIBLE_DEVICES=0 # Test multiple entropy thresholds ENTROPIES="0.23 0.28 0.46" for ENTROPY in $ENTROPIES; do echo "Testing entropy threshold: $ENTROPY" python examples/masked_run_highway_glue.py \ --model_type albert \ --model_name_or_path ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --task_name SST-2 \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size 1 \ --overwrite_output_dir \ --output_dir ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --plot_data_dir ./plotting/ \ --early_exit_entropy $ENTROPY \ --eval_highway \ --overwrite_cache done ``` -------------------------------- ### Set CUDA Device Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Configures the visible CUDA devices. ```python !export CUDA_VISIBLE_DEVICES=0 ``` -------------------------------- ### Push Changes to Your Fork Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Push your local branch with the new changes to your fork on GitHub. This makes your contributions visible and ready for a pull request. ```bash $ git push -u origin a-descriptive-name-for-my-changes ``` -------------------------------- ### Train Keras Model Source: https://github.com/harvard-acc/edgebert/blob/main/sw/Entropy_LUT/entropypredictor.ipynb Trains the compiled Keras model using the prepared training data (x_train, y_train) for 3 epochs. Verbose output is enabled. ```python model.fit(x_train, y_train, epochs=3, verbose=1) ``` -------------------------------- ### Evaluate Early Exit Performance Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Evaluates the model performance using early exit thresholds. ```python %%shell ENTROPIES="0.23 0.28 0.46" for ENTROPY in $ENTROPIES; do echo $ENTROPY python ../examples/masked_run_highway_glue.py --model_type albert \ --model_name_or_path ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --task_name SST-2 \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size=1 \ --overwrite_output_dir \ --output_dir ./saved_models/masked_albert/SST-2/bertarized_two_stage_pruned_0.6 \ --plot_data_dir ./plotting/ \ --early_exit_entropy $ENTROPY \ --eval_highway \ --overwrite_cache done ``` -------------------------------- ### Clone EdgeBERT Repository Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Clones the EdgeBERT repository from GitHub. ```python !git clone https://$GITHUB_AUTH@github.com/chooper1/EdgeBERT.git ``` -------------------------------- ### Run Custom Tokenizer Tests with Pytest Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Execute tests for custom tokenizers by setting the RUN_CUSTOM_TOKENIZERS environment variable to 'yes'. These tests do not run by default. ```bash RUN_CUSTOM_TOKENIZERS=yes python -m pytest -n auto --dist=loadfile -s -v ./tests/ ``` -------------------------------- ### Dvfs Hardware Dynamic Voltage Frequency Scaling Controller Source: https://context7.com/harvard-acc/edgebert/llms.txt Implements the Dvfs module for dynamic voltage and frequency scaling. It uses an entropy value to select appropriate V/F settings from lookup tables. ```cpp // Dvfs.h - Dynamic Voltage Frequency Scaling controller SC_MODULE(Dvfs) { public: sc_in_clk clk; sc_in rst; // Inputs Connections::In start; Connections::In dvfs_config; Connections::In enpy_val_in; // DCO and LDO lookup table configurations Connections::In dco_config_a; // 5 DCO values Connections::In dco_config_b; // 5 DCO values Connections::In ldo_config_a; // 4 LDO values Connections::In ldo_config_b; // 4 LDO values // Outputs to DCO and LDO Connections::Out dco_sel_out; // 6-bit DCO selector Connections::Out ldo_sel_out; // 8-bit LDO selector void DvfsRun() { Reset(); while(1) { switch (state) { case SCALE_ENPY: // Scale entropy value for LUT indexing enpy_val_scaled = enpy_val_reg / enpy_scale; break; case PUSH_VF: // Lookup table maps entropy to V/F settings // Lower entropy = higher confidence = can use lower V/F if (enpy_val_scaled < 256) { dco_sel_out.Push(dco_val_config_a[0]); ldo_sel_out.Push(ldo_val_config_a[0]); } else if (enpy_val_scaled < 512) { dco_sel_out.Push(dco_val_config_a[1]); ldo_sel_out.Push(ldo_val_config_a[1]); } // ... additional thresholds for 16 V/F levels else if (enpy_val_scaled >= 28672) { dco_sel_out.Push(dco_val_config_c[4]); ldo_sel_out.Push(ldo_val_config_d[3]); } break; } wait(); } } }; ``` -------------------------------- ### Evaluate Model Performance Source: https://github.com/harvard-acc/edgebert/blob/main/sw/Entropy_LUT/entropypredictor.ipynb Evaluates the trained model on the test dataset (x_test, y_test) to determine the loss. The model summary is commented out. ```python #check prediction val_loss = model.evaluate(x_test, y_test) #model.summary() ``` -------------------------------- ### Calculate Prediction Entropy Source: https://context7.com/harvard-acc/edgebert/llms.txt Computes entropy from logits to measure prediction confidence for early exit logic. ```python import torch def entropy(x): """ Compute entropy from logits (before softmax). Lower entropy indicates higher prediction confidence. Args: x: torch.Tensor of logits with shape (batch_size, num_classes) Returns: torch.Tensor of entropy values with shape (batch_size,) """ exp_x = torch.exp(x) A = torch.sum(exp_x, dim=1) # sum of exp(x_i) B = torch.sum(x * exp_x, dim=1) # sum of x_i * exp(x_i) return torch.log(A) - B / A # Usage example: logits = torch.tensor([[2.0, 1.0, 0.1], [0.5, 0.5, 0.5]]) ent = entropy(logits) ``` -------------------------------- ### Run Slow Tests with Pytest Source: https://github.com/harvard-acc/edgebert/blob/main/sw/EdgeBERT/transformers/CONTRIBUTING.md Execute all tests, including slow ones, by setting the RUN_SLOW environment variable to 'yes'. This may require significant disk space and bandwidth. ```bash RUN_SLOW=yes python -m pytest -n auto --dist=loadfile -s -v ./tests/ ``` ```bash RUN_SLOW=yes python -m pytest -n auto --dist=loadfile -s -v ./examples/ ``` -------------------------------- ### Train entropy lookup table for early exit prediction Source: https://context7.com/harvard-acc/edgebert/llms.txt Trains linear regression models to predict entropy at later layers based on early layer entropy, then saves the results to a CSV file. ```python def train_lookup_table(data, predict_layer=1): """ Train models to predict entropy at each layer from early layer entropy. Args: data: Array of shape (num_samples, num_layers) predict_layer: Which layer's entropy to use as predictor Returns: lookup_table: Array mapping entropy bins to predicted layer entropies """ X = data[:, :predict_layer] models = [] for target_layer in range(predict_layer, data.shape[1]): y = data[:, target_layer] model = LinearRegression() model.fit(X, y) models.append(model) # Create discretized lookup table entropy_bins = np.linspace(0, 2, 100) lookup_table = np.zeros((len(entropy_bins), len(models) + 1)) lookup_table[:, 0] = entropy_bins for i, ent in enumerate(entropy_bins): X_pred = np.array([[ent]]) for j, model in enumerate(models): lookup_table[i, j+1] = model.predict(X_pred)[0] return lookup_table # Generate and save lookup table lookup_table = train_lookup_table(train_data, predict_layer=1) np.savetxt('sst2_lookup_table_opt.csv', lookup_table, delimiter=',') ``` -------------------------------- ### Prune Model Weights Source: https://context7.com/harvard-acc/edgebert/llms.txt Apply binary masks to remove zero-valued weights from the trained model to create a deployment-ready version. ```bash #!/bin/bash export CUDA_VISIBLE_DEVICES=0 python examples/bertarize.py \ --pruning_method magnitude \ --threshold 0.5 \ --model_name_or_path ./saved_models/masked_albert/SST-2/two_stage_pruned_0.5 ``` -------------------------------- ### TopAccel SystemC Module Definition Source: https://context7.com/harvard-acc/edgebert/llms.txt Defines the top-level SystemC module for the EdgeBERT accelerator, connecting various internal modules and interfaces. ```cpp // TopAccel.h - Top-level accelerator module SC_MODULE(TopAccel) { public: sc_in_clk clk; sc_in rst; // IRQ and DVFS outputs sc_out interrupt; sc_out edgebert_dco_cc_sel; // DCO frequency control sc_out edgebert_ldo_res_sel; // LDO voltage control // AXI interfaces for data, mask, input, and auxiliary memory typename spec::AxiData::axi4_data::read::template master<> if_data_rd; typename spec::AxiData::axi4_data::write::template master<> if_data_wr; // Internal modules PUModule pu_inst; // Processing Unit with sparse PE GBModule gb_inst; // Global Buffer with LayerNorm, Softmax Control ct_inst; // Configuration and control MaskAxi ma_inst; // Mask memory AXI interface InputAxi ia_inst; // Input memory AXI interface AuxAxi aa_inst; // Auxiliary memory AXI interface SC_HAS_PROCESS(TopAccel); TopAccel(sc_module_name name_) : sc_module(name_) { // Connect processing unit pu_inst.clk(clk); pu_inst.rst(rst); pu_inst.accel_config(accel_config); // Connect global buffer with DVFS gb_inst.clk(clk); gb_inst.rst(rst); gb_inst.dco_sel_out(dco_sel_out); gb_inst.ldo_sel_out(ldo_sel_out); gb_inst.enpy_status(enpy_status); // Connect control unit ct_inst.clk(clk); ct_inst.rst(rst); ct_inst.interrupt(interrupt); ct_inst.edgebert_dco_cc_sel(edgebert_dco_cc_sel); ct_inst.edgebert_ldo_res_sel(edgebert_ldo_res_sel); } }; ``` -------------------------------- ### AlbertTransformer Early Exit Implementation Source: https://context7.com/harvard-acc/edgebert/llms.txt Implements early exit in AlbertTransformer using highway classifiers. Requires configuration for entropy prediction and lookup tables. ```python class AlbertTransformer(nn.Module): def __init__(self, config, params): super().__init__() self.config = config self.embedding_hidden_mapping_in = nn.Linear( config.embedding_size, config.hidden_size ) self.albert_layer_groups = nn.ModuleList([ AlbertLayerGroup(config, params) for _ in range(config.num_hidden_groups) ]) # Highway classifiers for early exit self.highway = nn.ModuleList([ AlbertHighway(config) for _ in range(config.num_hidden_layers) ]) self.early_exit_entropy = [-1] * config.num_hidden_layers # Entropy prediction configuration if config.entropy_predictor: self.lookup_table = np.loadtxt( config.lookup_table_file, delimiter="," ) self.predict_layer = config.predict_layer def set_early_exit_entropy(self, threshold): """Set entropy threshold for all layers.""" for i in range(len(self.early_exit_entropy)): self.early_exit_entropy[i] = threshold def forward(self, hidden_states, attention_mask=None, head_mask=None): hidden_states = self.embedding_hidden_mapping_in(hidden_states) for i in range(self.config.num_hidden_layers): group_idx = int(i / (self.config.num_hidden_layers / self.config.num_hidden_groups)) # Process through layer group layer_output = self.albert_layer_groups[group_idx]( hidden_states, attention_mask, head_mask ) hidden_states = layer_output[0] # Compute highway exit highway_exit = self.highway[i]((hidden_states,)) highway_logits = highway_exit[0] highway_entropy = entropy(highway_logits) # Early exit if entropy below threshold if not self.training: if highway_entropy < self.early_exit_entropy[i]: raise HighwayException( (highway_logits,), exit_layer=i+1 ) return (hidden_states,) ``` -------------------------------- ### Configure Masked ALBERT for EdgeBERT Source: https://context7.com/harvard-acc/edgebert/llms.txt Defines the configuration class for EdgeBERT models, including parameters for pruning, early exit, and entropy prediction. ```python from transformers import AlbertConfig class MaskedAlbertConfig(AlbertConfig): """Configuration for EdgeBERT masked ALBERT model.""" def __init__( self, # Standard ALBERT config vocab_size=30000, embedding_size=128, hidden_size=768, num_hidden_layers=12, num_hidden_groups=1, num_attention_heads=12, # Pruning configuration pruning_method="magnitude", # magnitude, topK, l0, sigmoied_threshold mask_init="constant", mask_scale=0.0, # Early exit configuration one_class=False, # Share highway classifier across layers entropy_predictor=False, predict_layer=1, predict_average_layers=0, lookup_table_file="./lookup_table.csv", extra_layer=False, get_predict_acc=False, no_ee_before=False, **kwargs ): super().__init__( vocab_size=vocab_size, embedding_size=embedding_size, hidden_size=hidden_size, num_hidden_layers=num_hidden_layers, num_hidden_groups=num_hidden_groups, num_attention_heads=num_attention_heads, **kwargs ) self.pruning_method = pruning_method self.mask_init = mask_init self.mask_scale = mask_scale self.one_class = one_class self.entropy_predictor = entropy_predictor self.predict_layer = predict_layer self.lookup_table_file = lookup_table_file # Usage example: config = MaskedAlbertConfig( pruning_method="magnitude", entropy_predictor=True, predict_layer=1, lookup_table_file="./sst2_lookup_table_opt.csv" ) ``` -------------------------------- ### Train Pruned Model Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Trains a pruned model using the masked_run_highway_glue script. ```python !python ../examples/masked_run_highway_glue.py --model_type masked_albert \ --model_name_or_path albert-base-v2 \ --task_name SST-2 \ --do_train \ --do_eval \ --do_lower_case \ --data_dir ./glue_data/SST-2 \ --max_seq_length 128 \ --per_gpu_eval_batch_size=1 \ --per_gpu_train_batch_size=64 \ --learning_rate 3e-5 \ --num_train_epochs 5 \ --overwrite_output_dir \ --seed 42 \ --output_dir ./saved_models/masked_albert/SST-2/two_stage_pruned_0.6 \ --plot_data_dir ./plotting/ \ --save_steps 0 \ --overwrite_cache \ --eval_after_first_stage \ --warmup_steps 1000 \ --mask_scores_learning_rate 1e-2 \ --initial_threshold 1 --final_threshold 0.6 \ --initial_warmup 2 --final_warmup 3 \ --pruning_method magnitude --mask_init constant --mask_scale 0. \ --teacher_type albert_teacher --teacher_name_or_path ./saved_models/albert-base/SST-2/teacher \ --alpha_ce 0.1 --alpha_distil 0.9 ``` -------------------------------- ### Define and Compile Keras Sequential Model Source: https://github.com/harvard-acc/edgebert/blob/main/sw/Entropy_LUT/entropypredictor.ipynb Defines a Keras Sequential model with multiple Dense layers. The model is compiled using the Adam optimizer and Mean Squared Error loss function. ```python model = Sequential() model.add(Dense(64, activation='relu', input_dim = 1)) #input layer model.add(Dense(64, activation='relu')) model.add(Dense(64, activation='relu')) model.add(Dense(64, activation='relu')) #model.add(Dense(64, activation='linear')) model.add(Dense(10-start_layer)) # output layer model.compile( optimizer='adam', loss='mean_squared_error' ) ``` -------------------------------- ### Bertarize Model Source: https://github.com/harvard-acc/edgebert/blob/main/sw/edgebert.ipynb Converts the pruned model into a bertarized format. ```python !python ../examples/bertarize.py \ --pruning_method magnitude \ --threshold 0.6 \ --model_name_or_path ./saved_models/masked_albert/SST-2/two_stage_pruned_0.6 \ ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.