|
1 | 1 | #!/bin/bash |
2 | 2 |
|
3 | | -# Parameters |
4 | | -IFS=',' read -r -a MODEL_CAPACITY_PAIRS <<< "$1" # Split the comma-separated model and capacity pairs into an array |
| 3 | +# Default Models and Capacities (Comma-separated in "model:capacity" format) |
| 4 | +DEFAULT_MODEL_CAPACITY="gpt-4o:30,text-embedding-ada-002:80,gpt-4:30" |
| 5 | + |
| 6 | +# Convert the comma-separated string into an array |
| 7 | +IFS=',' read -r -a MODEL_CAPACITY_PAIRS <<< "$DEFAULT_MODEL_CAPACITY" |
| 8 | + |
| 9 | +# Default Regions to check (Comma-separated, now configurable) |
| 10 | +DEFAULT_REGIONS="eastus,uksouth,eastus2,northcentralus,swedencentral,westus,westus2,southcentralus,canadacentral" |
| 11 | +IFS=',' read -r -a DEFAULT_REGION_ARRAY <<< "$DEFAULT_REGIONS" |
| 12 | + |
| 13 | +# Read parameters (if any) |
| 14 | +IFS=',' read -r -a USER_PROVIDED_PAIRS <<< "$1" |
5 | 15 | USER_REGION="$2" |
6 | 16 |
|
7 | | -if [ ${#MODEL_CAPACITY_PAIRS[@]} -lt 1 ]; then |
8 | | - echo "❌ ERROR: At least one model and capacity pairs must be provided as arguments." |
9 | | - exit 1 |
| 17 | +IS_USER_PROVIDED_PAIRS=false |
| 18 | + |
| 19 | +if [ ${#USER_PROVIDED_PAIRS[@]} -lt 1 ]; then |
| 20 | + echo "No parameters provided, using default model-capacity pairs: ${MODEL_CAPACITY_PAIRS[*]}" |
| 21 | +else |
| 22 | + echo "Using provided model and capacity pairs: ${USER_PROVIDED_PAIRS[*]}" |
| 23 | + IS_USER_PROVIDED_PAIRS=true |
| 24 | + MODEL_CAPACITY_PAIRS=("${USER_PROVIDED_PAIRS[@]}") |
10 | 25 | fi |
11 | 26 |
|
12 | | -# Extract model names and required capacities into arrays |
13 | | -declare -a MODEL_NAMES |
14 | | -declare -a CAPACITIES |
| 27 | +declare -a FINAL_MODEL_NAMES |
| 28 | +declare -a FINAL_CAPACITIES |
| 29 | +declare -a TABLE_ROWS |
15 | 30 |
|
16 | 31 | for PAIR in "${MODEL_CAPACITY_PAIRS[@]}"; do |
17 | | - MODEL_NAME=$(echo "$PAIR" | cut -d':' -f1) |
| 32 | + MODEL_NAME=$(echo "$PAIR" | cut -d':' -f1 | tr '[:upper:]' '[:lower:]') |
18 | 33 | CAPACITY=$(echo "$PAIR" | cut -d':' -f2) |
19 | 34 |
|
20 | 35 | if [ -z "$MODEL_NAME" ] || [ -z "$CAPACITY" ]; then |
21 | 36 | echo "❌ ERROR: Invalid model and capacity pair '$PAIR'. Both model and capacity must be specified." |
22 | 37 | exit 1 |
23 | 38 | fi |
24 | 39 |
|
25 | | - MODEL_NAMES+=("$MODEL_NAME") |
26 | | - CAPACITIES+=("$CAPACITY") |
27 | | -done |
28 | | - |
29 | | -echo "🔄 Using Models: ${MODEL_NAMES[*]} with respective Capacities: ${CAPACITIES[*]}" |
| 40 | + FINAL_MODEL_NAMES+=("$MODEL_NAME") |
| 41 | + FINAL_CAPACITIES+=("$CAPACITY") |
30 | 42 |
|
31 | | -echo "🔄 Fetching available Azure subscriptions..." |
32 | | -SUBSCRIPTIONS=$(az account list --query "[?state=='Enabled'].{Name:name, ID:id}" --output tsv) |
33 | | -SUB_COUNT=$(echo "$SUBSCRIPTIONS" | wc -l) |
34 | | - |
35 | | -if [ "$SUB_COUNT" -eq 1 ]; then |
36 | | - # If only one subscription, automatically select it |
37 | | - AZURE_SUBSCRIPTION_ID=$(echo "$SUBSCRIPTIONS" | awk '{print $2}') |
38 | | - echo "✅ Using the only available subscription: $AZURE_SUBSCRIPTION_ID" |
39 | | -else |
40 | | - # If multiple subscriptions exist, prompt the user to choose one |
41 | | - echo "Multiple subscriptions found:" |
42 | | - echo "$SUBSCRIPTIONS" | awk '{print NR")", $1, "-", $2}' |
43 | | - |
44 | | - while true; do |
45 | | - echo "Enter the number of the subscription to use:" |
46 | | - read SUB_INDEX |
47 | | - |
48 | | - # Validate user input |
49 | | - if [[ "$SUB_INDEX" =~ ^[0-9]+$ ]] && [ "$SUB_INDEX" -ge 1 ] && [ "$SUB_INDEX" -le "$SUB_COUNT" ]; then |
50 | | - AZURE_SUBSCRIPTION_ID=$(echo "$SUBSCRIPTIONS" | awk -v idx="$SUB_INDEX" 'NR==idx {print $2}') |
51 | | - echo "✅ Selected Subscription: $AZURE_SUBSCRIPTION_ID" |
52 | | - break |
53 | | - else |
54 | | - echo "❌ Invalid selection. Please enter a valid number from the list." |
55 | | - fi |
56 | | - done |
57 | | -fi |
58 | | - |
59 | | -# Set the selected subscription |
60 | | -az account set --subscription "$AZURE_SUBSCRIPTION_ID" |
61 | | -echo "🎯 Active Subscription: $(az account show --query '[name, id]' --output table)" |
| 43 | +done |
62 | 44 |
|
63 | | -# List of regions to check |
64 | | -DEFAULT_REGIONS=("eastus" "uksouth" "eastus2" "northcentralus" "swedencentral" "westus" "westus2" "southcentralus" "canadacentral") |
| 45 | +echo "🔄 Using Models: ${FINAL_MODEL_NAMES[*]} with respective Capacities: ${FINAL_CAPACITIES[*]}" |
| 46 | +echo "----------------------------------------" |
65 | 47 |
|
66 | | -# Prioritize user-provided region if given |
| 48 | +# Check if the user provided a region, if not, use the default regions |
67 | 49 | if [ -n "$USER_REGION" ]; then |
68 | | - # Ensure the user-provided region is checked first |
69 | | - REGIONS=("$USER_REGION" "${DEFAULT_REGIONS[@]}") |
| 50 | + echo "🔍 User provided region: $USER_REGION" |
| 51 | + IFS=',' read -r -a REGIONS <<< "$USER_REGION" |
70 | 52 | else |
71 | | - REGIONS=("${DEFAULT_REGIONS[@]}") |
| 53 | + echo "No region specified, using default regions: ${DEFAULT_REGION_ARRAY[*]}" |
| 54 | + REGIONS=("${DEFAULT_REGION_ARRAY[@]}") |
| 55 | + APPLY_OR_CONDITION=true |
72 | 56 | fi |
73 | 57 |
|
74 | 58 | echo "✅ Retrieved Azure regions. Checking availability..." |
| 59 | +INDEX=1 |
75 | 60 |
|
76 | 61 | VALID_REGIONS=() |
77 | 62 | for REGION in "${REGIONS[@]}"; do |
78 | 63 | echo "----------------------------------------" |
79 | 64 | echo "🔍 Checking region: $REGION" |
80 | 65 |
|
81 | | - # Fetch quota information for the region |
82 | | - QUOTA_INFO=$(az cognitiveservices usage list --location "$REGION" --output json) |
| 66 | + QUOTA_INFO=$(az cognitiveservices usage list --location "$REGION" --output json | tr '[:upper:]' '[:lower:]') |
83 | 67 | if [ -z "$QUOTA_INFO" ]; then |
84 | 68 | echo "⚠️ WARNING: Failed to retrieve quota for region $REGION. Skipping." |
85 | 69 | continue |
86 | 70 | fi |
87 | 71 |
|
88 | | - # Initialize a flag to track if both models have sufficient quota in the region |
89 | | - BOTH_MODELS_AVAILABLE=true |
90 | | - |
91 | | - for index in "${!MODEL_NAMES[@]}"; do |
92 | | - MODEL_NAME="${MODEL_NAMES[$index]}" |
93 | | - REQUIRED_CAPACITY="${CAPACITIES[$index]}" |
94 | | - |
95 | | - echo "🔍 Checking model: $MODEL_NAME with required capacity: $REQUIRED_CAPACITY" |
96 | | - |
97 | | - # Extract model quota information |
98 | | - MODEL_INFO=$(echo "$QUOTA_INFO" | awk -v model="\"value\": \"OpenAI.Standard.$MODEL_NAME\"" ' |
99 | | - BEGIN { RS="},"; FS="," } |
100 | | - $0 ~ model { print $0 } |
101 | | - ') |
102 | | - |
103 | | - if [ -z "$MODEL_INFO" ]; then |
104 | | - echo "⚠️ WARNING: No quota information found for model: OpenAI.Standard.$MODEL_NAME in $REGION. Skipping." |
105 | | - BOTH_MODELS_AVAILABLE=false |
106 | | - break # If any model is not available, no need to check further for this region |
107 | | - fi |
108 | | - |
109 | | - CURRENT_VALUE=$(echo "$MODEL_INFO" | awk -F': ' '/"currentValue"/ {print $2}' | tr -d ',' | tr -d ' ') |
110 | | - LIMIT=$(echo "$MODEL_INFO" | awk -F': ' '/"limit"/ {print $2}' | tr -d ',' | tr -d ' ') |
| 72 | + TEXT_EMBEDDING_AVAILABLE=false |
| 73 | + AT_LEAST_ONE_MODEL_AVAILABLE=false |
| 74 | + TEMP_TABLE_ROWS=() |
111 | 75 |
|
112 | | - CURRENT_VALUE=${CURRENT_VALUE:-0} |
113 | | - LIMIT=${LIMIT:-0} |
| 76 | + for index in "${!FINAL_MODEL_NAMES[@]}"; do |
| 77 | + MODEL_NAME="${FINAL_MODEL_NAMES[$index]}" |
| 78 | + REQUIRED_CAPACITY="${FINAL_CAPACITIES[$index]}" |
| 79 | + FOUND=false |
| 80 | + INSUFFICIENT_QUOTA=false |
114 | 81 |
|
115 | | - CURRENT_VALUE=$(echo "$CURRENT_VALUE" | cut -d'.' -f1) |
116 | | - LIMIT=$(echo "$LIMIT" | cut -d'.' -f1) |
117 | | - |
118 | | - AVAILABLE=$((LIMIT - CURRENT_VALUE)) |
119 | | - |
120 | | - echo "✅ Model: OpenAI.Standard.$MODEL_NAME | Used: $CURRENT_VALUE | Limit: $LIMIT | Available: $AVAILABLE" |
121 | | - |
122 | | - # Check if quota is sufficient |
123 | | - if [ "$AVAILABLE" -lt "$REQUIRED_CAPACITY" ]; then |
124 | | - echo "❌ ERROR: 'OpenAI.Standard.$MODEL_NAME' in $REGION has insufficient quota. Required: $REQUIRED_CAPACITY, Available: $AVAILABLE" |
125 | | - echo "➡️ To request a quota increase, visit: https://aka.ms/oai/stuquotarequest" |
126 | | - BOTH_MODELS_AVAILABLE=false |
127 | | - break |
| 82 | + if [ "$MODEL_NAME" = "text-embedding-ada-002" ]; then |
| 83 | + MODEL_TYPES=("openai.standard.$MODEL_NAME") |
| 84 | + else |
| 85 | + MODEL_TYPES=("openai.standard.$MODEL_NAME" "openai.globalstandard.$MODEL_NAME") |
128 | 86 | fi |
| 87 | + |
| 88 | + for MODEL_TYPE in "${MODEL_TYPES[@]}"; do |
| 89 | + FOUND=false |
| 90 | + INSUFFICIENT_QUOTA=false |
| 91 | + echo "🔍 Checking model: $MODEL_NAME with required capacity: $REQUIRED_CAPACITY ($MODEL_TYPE)" |
| 92 | + |
| 93 | + MODEL_INFO=$(echo "$QUOTA_INFO" | awk -v model="\"value\": \"$MODEL_TYPE\"" ' |
| 94 | + BEGIN { RS="},"; FS="," } |
| 95 | + $0 ~ model { print $0 } |
| 96 | + ') |
| 97 | + |
| 98 | + if [ -z "$MODEL_INFO" ]; then |
| 99 | + FOUND=false |
| 100 | + echo "⚠️ WARNING: No quota information found for model: $MODEL_NAME in region: $REGION for model type: $MODEL_TYPE." |
| 101 | + continue |
| 102 | + fi |
| 103 | + |
| 104 | + if [ -n "$MODEL_INFO" ]; then |
| 105 | + FOUND=true |
| 106 | + CURRENT_VALUE=$(echo "$MODEL_INFO" | awk -F': ' '/"currentvalue"/ {print $2}' | tr -d ',' | tr -d ' ') |
| 107 | + LIMIT=$(echo "$MODEL_INFO" | awk -F': ' '/"limit"/ {print $2}' | tr -d ',' | tr -d ' ') |
| 108 | + |
| 109 | + CURRENT_VALUE=${CURRENT_VALUE:-0} |
| 110 | + LIMIT=${LIMIT:-0} |
| 111 | + |
| 112 | + CURRENT_VALUE=$(echo "$CURRENT_VALUE" | cut -d'.' -f1) |
| 113 | + LIMIT=$(echo "$LIMIT" | cut -d'.' -f1) |
| 114 | + |
| 115 | + AVAILABLE=$((LIMIT - CURRENT_VALUE)) |
| 116 | + echo "✅ Model: $MODEL_TYPE | Used: $CURRENT_VALUE | Limit: $LIMIT | Available: $AVAILABLE" |
| 117 | + |
| 118 | + if [ "$AVAILABLE" -ge "$REQUIRED_CAPACITY" ]; then |
| 119 | + FOUND=true |
| 120 | + if [ "$MODEL_NAME" = "text-embedding-ada-002" ]; then |
| 121 | + TEXT_EMBEDDING_AVAILABLE=true |
| 122 | + fi |
| 123 | + AT_LEAST_ONE_MODEL_AVAILABLE=true |
| 124 | + TEMP_TABLE_ROWS+=("$(printf "| %-4s | %-20s | %-60s | %-10s | %-10s | %-10s |" "$INDEX" "$REGION" "$MODEL_TYPE" "$LIMIT" "$CURRENT_VALUE" "$AVAILABLE")") |
| 125 | + else |
| 126 | + INSUFFICIENT_QUOTA=true |
| 127 | + fi |
| 128 | + fi |
| 129 | + |
| 130 | + if [ "$FOUND" = false ]; then |
| 131 | + echo "❌ No models found for model: $MODEL_NAME in region: $REGION (${MODEL_TYPES[*]})" |
| 132 | + elif [ "$INSUFFICIENT_QUOTA" = true ]; then |
| 133 | + echo "⚠️ Model $MODEL_NAME in region: $REGION has insufficient quota (${MODEL_TYPES[*]})." |
| 134 | + fi |
| 135 | + done |
129 | 136 | done |
130 | 137 |
|
131 | | - # If both models have sufficient quota, add region to valid regions |
132 | | - if [ "$BOTH_MODELS_AVAILABLE" = true ]; then |
133 | | - echo "✅ All models have sufficient quota in $REGION." |
| 138 | +if { [ "$IS_USER_PROVIDED_PAIRS" = true ] && [ "$INSUFFICIENT_QUOTA" = false ] && [ "$FOUND" = true ]; } || { [ "$TEXT_EMBEDDING_AVAILABLE" = true ] && { [ "$APPLY_OR_CONDITION" != true ] || [ "$AT_LEAST_ONE_MODEL_AVAILABLE" = true ]; }; }; then |
134 | 139 | VALID_REGIONS+=("$REGION") |
| 140 | + TABLE_ROWS+=("${TEMP_TABLE_ROWS[@]}") |
| 141 | + INDEX=$((INDEX + 1)) |
| 142 | + elif [ ${#USER_PROVIDED_PAIRS[@]} -eq 0 ]; then |
| 143 | + echo "🚫 Skipping $REGION as it does not meet quota requirements." |
135 | 144 | fi |
| 145 | + |
136 | 146 | done |
137 | 147 |
|
138 | | -# Determine final result and display in table format |
139 | | -if [ ${#VALID_REGIONS[@]} -eq 0 ]; then |
140 | | - echo "----------------------------------------" |
141 | | - echo "❌ No region with sufficient quota found for all models. Blocking deployment." |
142 | | - echo "----------------------------------------" |
143 | | - exit 0 |
| 148 | +if [ ${#TABLE_ROWS[@]} -eq 0 ]; then |
| 149 | + echo "----------------------------------------------------------------------------------------------------------" |
| 150 | + |
| 151 | + echo "❌ No regions have sufficient quota for all required models. Please request a quota increase: https://aka.ms/oai/stuquotarequest" |
144 | 152 | else |
145 | | - echo "----------------------------------------" |
146 | | - echo "✅ Suggested Regions with Sufficient Quota" |
147 | | - echo "----------------------------------------" |
148 | | - printf "| %-5s | %-20s |\n" "No." "Region" |
149 | | - echo "----------------------------------------" |
150 | | - |
151 | | - INDEX=1 |
152 | | - for REGION in "${VALID_REGIONS[@]}"; do |
153 | | - printf "| %-5s | %-20s |\n" "$INDEX" "$REGION" |
154 | | - INDEX=$((INDEX + 1)) |
| 153 | + echo "----------------------------------------------------------------------------------------------------------" |
| 154 | + printf "| %-4s | %-20s | %-60s | %-10s | %-10s | %-10s |\n" "No." "Region" "Model Name" "Limit" "Used" "Available" |
| 155 | + echo "----------------------------------------------------------------------------------------------------------" |
| 156 | + for ROW in "${TABLE_ROWS[@]}"; do |
| 157 | + echo "$ROW" |
155 | 158 | done |
156 | | - |
157 | | - echo "----------------------------------------" |
158 | | - exit 0 |
| 159 | + echo "----------------------------------------------------------------------------------------------------------" |
| 160 | + echo "➡️ To request a quota increase, visit: https://aka.ms/oai/stuquotarequest" |
159 | 161 | fi |
| 162 | + |
| 163 | +echo "✅ Script completed." |
0 commit comments