Skip to content

Commit 1d08744

Browse files
authored
Howie/resolve quota (#126)
* resolve quota * prompt for quota * more changes * update * Change readme * resolve comment * resolve comments * add exit code 0 and check skip validaiton if user uses existing ai project resource
1 parent 23d110e commit 1d08744

11 files changed

+519
-46
lines changed

azure.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@ metadata:
77
88

99
hooks:
10-
preup:
10+
preprovision:
11+
posix:
12+
shell: sh
13+
run: chmod u+r+x ./scripts/set_default_models.sh; chmod u+r+x ./scripts/resolve_model_quota.sh; ./scripts/set_default_models.sh
14+
interactive: true
15+
continueOnError: false
16+
windows:
17+
shell: pwsh
18+
run: ./scripts/set_default_models.ps1
19+
interactive: true
20+
continueOnError: false
1121
postprovision:
1222
windows:
1323
shell: pwsh

docs/deploy_customization.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ azd env set AZURE_AI_AGENT_MODEL_VERSION 2024-07-18
5959

6060
### Setting capacity and deployment SKU
6161

62-
For quota regions, you may find yourself needing to modify the default capacity and deployment SKU. The default tokens per minute deployed in this template is 50,000.
62+
For quota regions, you may find yourself needing to modify the default capacity and deployment SKU using environment variables as below. The default tokens per minute deployed in this template is 80,000 for agent model and 50,000 for the embedding model that is enough for all operations. If the region has quota less the these numbers, you will be prompt to input a lower capacity up to the available limit.
6363

64-
Change the capacity (in thousands of tokens per minute) of the agent deployment:
64+
Change the default capacity (in thousands of tokens per minute) of the agent deployment:
6565

6666
```shell
6767
azd env set AZURE_AI_AGENT_DEPLOYMENT_CAPACITY 50
@@ -73,7 +73,7 @@ Change the SKU of the agent deployment:
7373
azd env set AZURE_AI_AGENT_DEPLOYMENT_SKU Standard
7474
```
7575

76-
Change the capacity (in thousands of tokens per minute) of the embeddings deployment:
76+
Change the default capacity (in thousands of tokens per minute) of the embeddings deployment:
7777

7878
```shell
7979
azd env set AZURE_AI_EMBED_DEPLOYMENT_CAPACITY 50

infra/main.parameters.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,40 +60,40 @@
6060
"value": "${AZURE_EXISTING_AGENT_ID}"
6161
},
6262
"agentDeploymentName": {
63-
"value": "${AZURE_AI_AGENT_MODEL_NAME=gpt-4o-mini}"
63+
"value": "${AZURE_AI_AGENT_MODEL_NAME}"
6464
},
6565
"agentModelFormat": {
66-
"value": "${AZURE_AI_AGENT_MODEL_FORMAT=OpenAI}"
66+
"value": "${AZURE_AI_AGENT_MODEL_FORMAT}"
6767
},
6868
"agentModelName": {
69-
"value": "${AZURE_AI_AGENT_MODEL_NAME=gpt-4o-mini}"
69+
"value": "${AZURE_AI_AGENT_MODEL_NAME}"
7070
},
7171
"agentModelVersion": {
72-
"value": "${AZURE_AI_AGENT_MODEL_VERSION=2024-07-18}"
72+
"value": "${AZURE_AI_AGENT_MODEL_VERSION}"
7373
},
7474
"agentDeploymentSku": {
75-
"value": "${AZURE_AI_AGENT_DEPLOYMENT_SKU=GlobalStandard}"
75+
"value": "${AZURE_AI_AGENT_DEPLOYMENT_SKU}"
7676
},
7777
"agentDeploymentCapacity": {
78-
"value": "${AZURE_AI_AGENT_DEPLOYMENT_CAPACITY=30}"
78+
"value": "${AZURE_AI_AGENT_DEPLOYMENT_CAPACITY}"
7979
},
8080
"embeddingDeploymentName": {
81-
"value": "${AZURE_AI_EMBED_DEPLOYMENT_NAME=text-embedding-3-small}"
81+
"value": "${AZURE_AI_EMBED_DEPLOYMENT_NAME}"
8282
},
8383
"embedModelFormat": {
84-
"value": "${AZURE_AI_EMBED_MODEL_FORMAT=OpenAI}"
84+
"value": "${AZURE_AI_EMBED_MODEL_FORMAT}"
8585
},
8686
"embedModelName": {
87-
"value": "${AZURE_AI_EMBED_MODEL_NAME=text-embedding-3-small}"
87+
"value": "${AZURE_AI_EMBED_MODEL_NAME}"
8888
},
8989
"embedModelVersion": {
90-
"value": "${AZURE_AI_EMBED_MODEL_VERSION=1}"
90+
"value": "${AZURE_AI_EMBED_MODEL_VERSION}"
9191
},
9292
"embedDeploymentSku": {
93-
"value": "${AZURE_AI_EMBED_DEPLOYMENT_SKU=Standard}"
93+
"value": "${AZURE_AI_EMBED_DEPLOYMENT_SKU}"
9494
},
9595
"embedDeploymentCapacity": {
96-
"value": "${AZURE_AI_EMBED_DEPLOYMENT_CAPACITY=30}"
96+
"value": "${AZURE_AI_EMBED_DEPLOYMENT_CAPACITY}"
9797
},
9898
"embeddingDeploymentDimensions": {
9999
"value": "${AZURE_AI_EMBED_DIMENSIONS=100}"

scripts/resolve_model_quota.ps1

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
param (
2+
[string]$Location,
3+
[string]$Model,
4+
[string]$Format,
5+
[string]$DeploymentType,
6+
[string]$CapacityEnvVarName,
7+
[int]$Capacity
8+
)
9+
10+
# Verify all required parameters are provided
11+
$MissingParams = @()
12+
13+
if (-not $Location) {
14+
$MissingParams += "location"
15+
}
16+
17+
if (-not $Model) {
18+
$MissingParams += "model"
19+
}
20+
21+
if (-not $Capacity) {
22+
$MissingParams += "capacity"
23+
}
24+
25+
if (-not $Format) {
26+
$MissingParams += "format"
27+
}
28+
29+
if (-not $DeploymentType) {
30+
$MissingParams += "deployment-type"
31+
}
32+
33+
if ($MissingParams.Count -gt 0) {
34+
Write-Error "❌ ERROR: Missing required parameters: $($MissingParams -join ', ')"
35+
Write-Host "Usage: .\resolve_model_quota.ps1 -Location <LOCATION> -Model <MODEL> -Format <FORMAT> -Capacity <CAPACITY> -CapacityEnvVarName <ENV_VAR_NAME> [-DeploymentType <DEPLOYMENT_TYPE>]"
36+
exit 1
37+
}
38+
39+
if ($DeploymentType -ne "Standard" -and $DeploymentType -ne "GlobalStandard") {
40+
Write-Error "❌ ERROR: Invalid deployment type: $DeploymentType. Allowed values are 'Standard' or 'GlobalStandard'."
41+
exit 1
42+
}
43+
44+
$ModelType = "$Format.$DeploymentType.$Model"
45+
46+
Write-Host "🔍 Checking quota for $ModelType in $Location ..."
47+
48+
# Get model quota information
49+
$ModelInfo = az cognitiveservices usage list --location $Location --query "[?name.value=='$ModelType'] | [0]" --output json | ConvertFrom-Json
50+
if (-not $ModelInfo) {
51+
Write-Error "❌ ERROR: No quota information found for model: $Model in location: $Location for model type: $ModelType."
52+
exit 1
53+
}
54+
55+
56+
$CurrentValue =$ModelInfo.currentValue
57+
$Limit = $ModelInfo.limit
58+
59+
$CurrentValue = [int]($CurrentValue -replace '\.0+$', '') # Remove decimals
60+
$Limit = [int]($Limit -replace '\.0+$', '') # Remove decimals
61+
62+
$Available = $Limit - $CurrentValue
63+
Write-Host "✅ Model available - Model: $ModelType | Used: $CurrentValue | Limit: $Limit | Available: $Available"
64+
65+
66+
if ($Available -lt $Capacity) {
67+
68+
# Determine newCapacity based on user prompt or availability
69+
# This logic assumes it will replace the subsequent lines that also set $newCapacity.
70+
if ($Available -ge 1) {
71+
$validInput = $false
72+
# $newCapacity will be set by user input if $Available >= 1
73+
do {
74+
$userInput = Read-Host "⚠️ ERROR: Insufficient quota. Available: $Available (in thousands of tokens per minute). Ideal is $Capacity. Please enter a new capacity (integer between 1 and $Available): "
75+
76+
$parsedInt = 0 # Variable to hold the parsed integer
77+
if ([int]::TryParse($userInput, [ref]$parsedInt)) {
78+
if ($parsedInt -ge 1 -and $parsedInt -le $Available) {
79+
$newCapacity = $parsedInt # Set $newCapacity to the user's valid choice
80+
$validInput = $true
81+
} else {
82+
Write-Warning "Invalid input. '$parsedInt' is not between 1 and $Available. Please try again."
83+
}
84+
} else {
85+
Write-Warning "Invalid input: '$userInput' is not a valid integer. Please try again."
86+
}
87+
} while (-not $validInput)
88+
azd env set $CapacityEnvVarName $newCapacity
89+
} else {
90+
# This case handles when $Available is 0 or less (though quota is typically non-negative).
91+
# Prompting for "between 1 and $Available" is not possible.
92+
Write-Error "❌ ERROR: Insufficient quota for model: $Model in location: $Location. Available: less than 1 (in thousands of tokens per minute), Requested: $Capacity."
93+
exit 1
94+
}
95+
96+
} else {
97+
Write-Host "✅ Sufficient quota for model: $Model in location: $Location. Available: $Available, Requested: $Capacity."
98+
}
99+
100+
exit 0

scripts/resolve_model_quota.sh

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#!/bin/bash
2+
3+
# Initialize variables
4+
Location=""
5+
Model=""
6+
Format=""
7+
DeploymentType=""
8+
CapacityEnvVarName=""
9+
Capacity=""
10+
11+
# Parse arguments
12+
while [[ $# -gt 0 ]]; do
13+
case "$1" in
14+
-Location)
15+
Location="$2"
16+
shift 2
17+
;;
18+
-Model)
19+
Model="$2"
20+
shift 2
21+
;;
22+
-DeploymentType)
23+
DeploymentType="$2"
24+
shift 2
25+
;;
26+
-CapacityEnvVarName)
27+
CapacityEnvVarName="$2"
28+
shift 2
29+
;;
30+
-Capacity)
31+
Capacity="$2"
32+
shift 2
33+
;;
34+
-Format)
35+
Format="$2"
36+
shift 2
37+
;;
38+
*)
39+
echo "❌ ERROR: Unknown parameter: $1"
40+
exit 1
41+
;;
42+
esac
43+
done
44+
45+
# Check for missing required parameters
46+
MissingParams=()
47+
[[ -z "$Location" ]] && MissingParams+=("location")
48+
[[ -z "$Model" ]] && MissingParams+=("model")
49+
[[ -z "$Capacity" ]] && MissingParams+=("capacity")
50+
[[ -z "$DeploymentType" ]] && MissingParams+=("deployment-type")
51+
52+
if [[ ${#MissingParams[@]} -gt 0 ]]; then
53+
echo "❌ ERROR: Missing required parameters: ${MissingParams[*]}"
54+
echo "Usage: ./resolve_model_quota.sh -Location <Location> -Model <Model> -Format <Format> -Capacity <CAPACITY> -CapacityEnvVarName <ENV_VAR_NAME> [-DeploymentType <DeploymentType>]"
55+
exit 1
56+
fi
57+
58+
if [[ "$DeploymentType" != "Standard" && "$DeploymentType" != "GlobalStandard" ]]; then
59+
echo "❌ ERROR: Invalid deployment type: $DeploymentType. Allowed values are 'Standard' or 'GlobalStandard'."
60+
exit 1
61+
fi
62+
63+
ModelType="$Format.$DeploymentType.$Model"
64+
65+
echo "🔍 Checking quota for $ModelType in $Location ..."
66+
67+
ModelInfo=$(az cognitiveservices usage list --location "$Location" --query "[?name.value=='$ModelType']" --output json | tr '[:upper:]' '[:lower:]')
68+
69+
if [ -z "$ModelInfo" ]; then
70+
echo "❌ ERROR: No quota information found for model: $Model in location: $Location for model type: $ModelType."
71+
exit 1
72+
fi
73+
74+
CurrentValue=$(echo "$ModelInfo" | awk -F': ' '/"currentvalue"/ {print $2}' | tr -d ',' | tr -d ' ')
75+
Limit=$(echo "$ModelInfo" | awk -F': ' '/"limit"/ {print $2}' | tr -d ',' | tr -d ' ')
76+
77+
CurrentValue=${CurrentValue:-0}
78+
Limit=${Limit:-0}
79+
80+
CurrentValue=$(echo "$CurrentValue" | cut -d'.' -f1)
81+
Limit=$(echo "$Limit" | cut -d'.' -f1)
82+
83+
Available=$((Limit - CurrentValue))
84+
echo "✅ Model available - Model: $ModelType | Used: $CurrentValue | Limit: $Limit | Available: $Available"
85+
86+
if [ "$Available" -lt "$Capacity" ]; then
87+
if [ "$Available" -ge 1 ]; then
88+
validInput=false
89+
while [ "$validInput" = false ]; do
90+
read -p "⚠️ ERROR: Insufficient quota. Available: $Available (in thousands of tokens per minute). Ideal was $Capacity. Please enter a new capacity (integer between 1 and $Available): " userInput
91+
92+
if [[ "$userInput" =~ ^[0-9]+$ ]]; then
93+
if [ "$userInput" -ge 1 ] && [ "$userInput" -le "$Available" ]; then
94+
newCapacity=$userInput
95+
validInput=true
96+
else
97+
echo "⚠️ WARNING: Invalid input. '$userInput' is not between 1 and $Available. Please try again." >&2
98+
fi
99+
else
100+
echo "⚠️ WARNING: Invalid input: '$userInput' is not a valid integer. Please try again." >&2
101+
fi
102+
done
103+
azd env set "$CapacityEnvVarName" "$newCapacity"
104+
else
105+
echo "❌ ERROR: Insufficient quota for model: $Model in location: $Location. Available: less than 1 (in thousands of tokens per minute), Requested: $Capacity." >&2
106+
exit 1
107+
fi
108+
else
109+
echo "✅ Sufficient quota for model: $Model in location: $Location. Available: $Available, Requested: $Capacity."
110+
fi
111+
112+
echo "Set exit code to 0"
113+
exit 0

0 commit comments

Comments
 (0)