mirror of
https://github.com/microsoft/BitNet.git
synced 2026-05-03 11:20:36 +00:00
278 lines
7.5 KiB
Bash
Executable File
278 lines
7.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Script: Test different GEMM parallel strategy performance
|
|
# Strategies: weight-parallel and no-parallel
|
|
# Thread counts: 1,2,4,8,12,16
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
GEMM_CONFIG="$PROJECT_ROOT/include/gemm-config.h"
|
|
GEMM_CONFIG_BACKUP="$PROJECT_ROOT/include/gemm-config.h.bak"
|
|
BUILD_DIR="$PROJECT_ROOT/build"
|
|
STATS_DIR="$PROJECT_ROOT/stats"
|
|
CSV_FILE="$STATS_DIR/test_parallel_strategy_benchmark.csv"
|
|
MODEL_PATH="$PROJECT_ROOT/models/BitNet-b1.58-2B-4T/ggml-model-original.gguf"
|
|
BENCHMARK_CMD="./build/bin/llama-bench"
|
|
THREADS_LIST="1 2 4 8 12 16"
|
|
|
|
# Color output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Check prerequisites
|
|
check_prerequisites() {
|
|
log_info "Checking prerequisites..."
|
|
|
|
if [ ! -f "$GEMM_CONFIG" ]; then
|
|
log_error "gemm-config.h not found: $GEMM_CONFIG"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$MODEL_PATH" ]; then
|
|
log_error "Model file not found: $MODEL_PATH"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$BUILD_DIR" ]; then
|
|
log_error "Build directory not found: $BUILD_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$BUILD_DIR/bin/llama-bench" ]; then
|
|
log_warn "llama-bench executable not found, building..."
|
|
build_project
|
|
fi
|
|
|
|
if [ ! -d "$STATS_DIR" ]; then
|
|
log_info "Creating stats directory..."
|
|
mkdir -p "$STATS_DIR"
|
|
fi
|
|
|
|
log_info "Prerequisites check completed"
|
|
}
|
|
|
|
# Backup original config file
|
|
backup_config() {
|
|
log_info "Backing up gemm-config.h..."
|
|
cp "$GEMM_CONFIG" "$GEMM_CONFIG_BACKUP"
|
|
log_info "Backup completed: $GEMM_CONFIG_BACKUP"
|
|
}
|
|
|
|
# Restore original config file
|
|
restore_config() {
|
|
if [ -f "$GEMM_CONFIG_BACKUP" ]; then
|
|
log_info "Restoring original gemm-config.h..."
|
|
cp "$GEMM_CONFIG_BACKUP" "$GEMM_CONFIG"
|
|
rm "$GEMM_CONFIG_BACKUP"
|
|
log_info "Restore completed"
|
|
else
|
|
log_warn "Backup file not found, skipping restore"
|
|
fi
|
|
}
|
|
|
|
# Set activation-parallel configuration (keep original ACT_PARALLEL)
|
|
set_activation_parallel() {
|
|
log_info "Configuration: activation-parallel (keeping #define ACT_PARALLEL)"
|
|
log_info "Configuration completed"
|
|
}
|
|
|
|
# Set weight-parallel configuration (remove ACT_PARALLEL)
|
|
set_weight_parallel() {
|
|
log_info "Configuration: weight-parallel (removing #define ACT_PARALLEL)"
|
|
|
|
# Remove ACT_PARALLEL definition
|
|
sed -i '/#define ACT_PARALLEL/d' "$GEMM_CONFIG"
|
|
|
|
# Verify modification
|
|
if grep -q "^#define ACT_PARALLEL" "$GEMM_CONFIG"; then
|
|
log_error "Failed to remove ACT_PARALLEL"
|
|
exit 1
|
|
fi
|
|
log_info "Configuration completed"
|
|
}
|
|
|
|
# Set no-parallel configuration (remove ACT_PARALLEL + modify SIZE to 1)
|
|
set_no_parallel() {
|
|
log_info "Configuration: no-parallel (removing #define ACT_PARALLEL + modifying SIZE to 1)"
|
|
|
|
# Remove ACT_PARALLEL definition
|
|
sed -i '/#define ACT_PARALLEL/d' "$GEMM_CONFIG"
|
|
|
|
# Modify all ROW_BLOCK_SIZE and COL_BLOCK_SIZE to 1
|
|
sed -i 's/#define ROW_BLOCK_SIZE [0-9]\+/#define ROW_BLOCK_SIZE 1/g' "$GEMM_CONFIG"
|
|
sed -i 's/#define COL_BLOCK_SIZE [0-9]\+/#define COL_BLOCK_SIZE 1/g' "$GEMM_CONFIG"
|
|
|
|
log_info "Configuration completed"
|
|
}
|
|
|
|
# Build project
|
|
build_project() {
|
|
log_info "Building project..."
|
|
cd "$PROJECT_ROOT"
|
|
|
|
if [ ! -f "$BUILD_DIR/Makefile" ]; then
|
|
log_info "First build, running cmake..."
|
|
cmake -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release > /dev/null 2>&1
|
|
fi
|
|
|
|
cd "$BUILD_DIR"
|
|
make -j$(nproc) llama-bench > /dev/null 2>&1
|
|
|
|
if [ ! -f "./bin/llama-bench" ]; then
|
|
log_error "Build failed"
|
|
exit 1
|
|
fi
|
|
|
|
log_info "Build completed"
|
|
cd "$PROJECT_ROOT"
|
|
}
|
|
|
|
# Run benchmark test
|
|
run_benchmark() {
|
|
local strategy=$1
|
|
local threads=$2
|
|
|
|
cd "$PROJECT_ROOT"
|
|
|
|
# Run llama-bench
|
|
local output=$($BENCHMARK_CMD -m "$MODEL_PATH" -p 128 -n 0 -t "$threads" -ngl 0 2>&1)
|
|
|
|
# Extract line containing "pp128"
|
|
local line=$(echo "$output" | grep "pp128" | tail -1)
|
|
|
|
if [ -z "$line" ]; then
|
|
return 1
|
|
fi
|
|
|
|
echo "$line"
|
|
}
|
|
|
|
# Extract throughput value from benchmark output
|
|
extract_throughput() {
|
|
local line=$1
|
|
|
|
# Remove any leading/trailing whitespace and log messages
|
|
# The line format is: | model | size | params | backend | threads | test | throughput |
|
|
# We need to extract the last field which contains the throughput in format "XXX.XX ± YY.YY"
|
|
local throughput=$(echo "$line" | awk -F'|' '{print $NF}' | xargs | sed 's/\[.*\]//' | xargs)
|
|
|
|
echo "$throughput"
|
|
}
|
|
|
|
# Initialize CSV file
|
|
init_csv() {
|
|
log_info "Initializing CSV file: $CSV_FILE"
|
|
|
|
cat > "$CSV_FILE" << 'EOF'
|
|
Strategy,Threads,Throughput
|
|
EOF
|
|
|
|
log_info "CSV file created"
|
|
}
|
|
|
|
# Add result to CSV
|
|
add_to_csv() {
|
|
local strategy=$1
|
|
local threads=$2
|
|
local throughput=$3
|
|
|
|
echo "$strategy,$threads,$throughput" >> "$CSV_FILE"
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
log_info "Starting GEMM parallel strategy benchmark tests"
|
|
log_info "================================================"
|
|
|
|
# Check prerequisites
|
|
check_prerequisites
|
|
|
|
# Backup original configuration
|
|
backup_config
|
|
|
|
# Initialize CSV file
|
|
init_csv
|
|
|
|
# Define strategies to test
|
|
local strategies=("activation-parallel" "weight-parallel" "no-parallel")
|
|
|
|
for strategy in "${strategies[@]}"; do
|
|
log_info "================================================"
|
|
log_info "Testing strategy: $strategy"
|
|
log_info "================================================"
|
|
|
|
# Restore to original configuration
|
|
restore_config
|
|
backup_config
|
|
|
|
# Apply configuration based on strategy
|
|
case $strategy in
|
|
activation-parallel)
|
|
set_activation_parallel
|
|
;;
|
|
weight-parallel)
|
|
set_weight_parallel
|
|
;;
|
|
no-parallel)
|
|
set_no_parallel
|
|
;;
|
|
esac
|
|
|
|
# Rebuild project to apply new configuration
|
|
log_info "Rebuilding project to apply new configuration..."
|
|
build_project
|
|
|
|
# Run test for each thread count
|
|
for threads in $THREADS_LIST; do
|
|
log_info ""
|
|
log_info "Strategy: $strategy, Threads: $threads"
|
|
|
|
# Run test (capture only output, not log messages)
|
|
local result=$(run_benchmark "$strategy" "$threads")
|
|
local test_status=$?
|
|
|
|
if [ $test_status -eq 0 ]; then
|
|
# Extract throughput value from the result line
|
|
local throughput=$(extract_throughput "$result")
|
|
log_info "Throughput: $throughput"
|
|
|
|
# Add to CSV
|
|
add_to_csv "$strategy" "$threads" "$throughput"
|
|
else
|
|
log_warn "Test failed for strategy $strategy, threads $threads"
|
|
fi
|
|
|
|
sleep 2 # Give system time to cool down
|
|
done
|
|
done
|
|
|
|
# Restore original configuration
|
|
restore_config
|
|
|
|
log_info "================================================"
|
|
log_info "Test completed!"
|
|
log_info "Results saved to: $CSV_FILE"
|
|
log_info "================================================"
|
|
|
|
# Display CSV content
|
|
log_info "CSV file content:"
|
|
cat "$CSV_FILE"
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|