@@ -11,6 +11,7 @@ import (
11
11
"strconv"
12
12
"strings"
13
13
14
+ "github.com/golang/glog"
14
15
"github.com/livepeer/ai-worker/worker"
15
16
)
16
17
@@ -64,15 +65,19 @@ func PipelineToCapability(pipeline string) (Capability, error) {
64
65
}
65
66
66
67
type AIModelConfig struct {
67
- Pipeline string `json:"pipeline"`
68
- ModelID string `json:"model_id"`
68
+ Pipeline string `json:"pipeline"`
69
+ ModelID string `json:"model_id"`
70
+ // used by worker
69
71
URL string `json:"url,omitempty"`
70
72
Token string `json:"token,omitempty"`
71
73
Warm bool `json:"warm,omitempty"`
72
- PricePerUnit JSONRat `json:"price_per_unit,omitempty"`
73
- PixelsPerUnit JSONRat `json:"pixels_per_unit,omitempty"`
74
- Currency string `json:"currency,omitempty"`
74
+ Capacity int `json:"capacity,omitempty"`
75
75
OptimizationFlags worker.OptimizationFlags `json:"optimization_flags,omitempty"`
76
+ // used by orchestrator
77
+ Gateway string `json:"gateway"`
78
+ PricePerUnit JSONRat `json:"price_per_unit,omitempty"`
79
+ PixelsPerUnit JSONRat `json:"pixels_per_unit,omitempty"`
80
+ Currency string `json:"currency,omitempty"`
76
81
}
77
82
78
83
func ParseAIModelConfigs (config string ) ([]AIModelConfig , error ) {
@@ -112,7 +117,7 @@ func ParseAIModelConfigs(config string) ([]AIModelConfig, error) {
112
117
return configs , nil
113
118
}
114
119
115
- // parseStepsFromModelID parses the number of inference steps from the model ID suffix.
120
+ // ParseStepsFromModelID parses the number of inference steps from the model ID suffix.
116
121
func ParseStepsFromModelID (modelID * string , defaultSteps float64 ) float64 {
117
122
numInferenceSteps := defaultSteps
118
123
@@ -127,3 +132,102 @@ func ParseStepsFromModelID(modelID *string, defaultSteps float64) float64 {
127
132
128
133
return numInferenceSteps
129
134
}
135
+
136
+ // AddAICapabilities adds AI capabilities to the node.
137
+ func (n * LivepeerNode ) AddAICapabilities (caps * Capabilities ) {
138
+ aiConstraints := caps .PerCapability ()
139
+ if aiConstraints == nil {
140
+ return
141
+ }
142
+
143
+ n .Capabilities .mutex .Lock ()
144
+ defer n .Capabilities .mutex .Unlock ()
145
+ for aiCapability , aiConstraint := range aiConstraints {
146
+ _ , capExists := n .Capabilities .constraints .perCapability [aiCapability ]
147
+ if ! capExists {
148
+ n .Capabilities .constraints .perCapability [aiCapability ] = & CapabilityConstraints {
149
+ Models : make (ModelConstraints ),
150
+ }
151
+ }
152
+
153
+ for modelId , modelConstraint := range aiConstraint .Models {
154
+ _ , modelExists := n .Capabilities .constraints .perCapability [aiCapability ].Models [modelId ]
155
+ if modelExists {
156
+ n .Capabilities .constraints .perCapability [aiCapability ].Models [modelId ].Capacity += modelConstraint .Capacity
157
+ } else {
158
+ n .Capabilities .constraints .perCapability [aiCapability ].Models [modelId ] = & ModelConstraint {Warm : modelConstraint .Warm , Capacity : modelConstraint .Capacity }
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ // RemoveAICapabilities removes AI capabilities from the node.
165
+ func (n * LivepeerNode ) RemoveAICapabilities (caps * Capabilities ) {
166
+ aiConstraints := caps .PerCapability ()
167
+ if aiConstraints == nil {
168
+ return
169
+ }
170
+
171
+ n .Capabilities .mutex .Lock ()
172
+ defer n .Capabilities .mutex .Unlock ()
173
+ for capability , constraint := range aiConstraints {
174
+ _ , ok := n .Capabilities .constraints .perCapability [capability ]
175
+ if ok {
176
+ for modelId , modelConstraint := range constraint .Models {
177
+ _ , modelExists := n .Capabilities .constraints .perCapability [capability ].Models [modelId ]
178
+ if modelExists {
179
+ n .Capabilities .constraints .perCapability [capability ].Models [modelId ].Capacity -= modelConstraint .Capacity
180
+ if n .Capabilities .constraints .perCapability [capability ].Models [modelId ].Capacity <= 0 {
181
+ delete (n .Capabilities .constraints .perCapability [capability ].Models , modelId )
182
+ }
183
+ } else {
184
+ glog .Errorf ("failed to remove AI capability capacity, model does not exist pipeline=%v modelID=%v" , capability , modelId )
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+
191
+ func (n * LivepeerNode ) ReserveAICapability (pipeline string , modelID string ) error {
192
+ cap , err := PipelineToCapability (pipeline )
193
+ if err != nil {
194
+ return err
195
+ }
196
+
197
+ _ , hasCap := n .Capabilities .constraints .perCapability [cap ]
198
+ if hasCap {
199
+ _ , hasModel := n .Capabilities .constraints .perCapability [cap ].Models [modelID ]
200
+ if hasModel {
201
+ n .Capabilities .mutex .Lock ()
202
+ defer n .Capabilities .mutex .Unlock ()
203
+ if n .Capabilities .constraints .perCapability [cap ].Models [modelID ].Capacity > 0 {
204
+ n .Capabilities .constraints .perCapability [cap ].Models [modelID ].Capacity -= 1
205
+ } else {
206
+ return fmt .Errorf ("failed to reserve AI capability capacity, model capacity is 0 pipeline=%v modelID=%v" , pipeline , modelID )
207
+ }
208
+ return nil
209
+ }
210
+ return fmt .Errorf ("failed to reserve AI capability capacity, model does not exist pipeline=%v modelID=%v" , pipeline , modelID )
211
+ }
212
+ return fmt .Errorf ("failed to reserve AI capability capacity, pipeline does not exist pipeline=%v modelID=%v" , pipeline , modelID )
213
+ }
214
+
215
+ func (n * LivepeerNode ) ReleaseAICapability (pipeline string , modelID string ) error {
216
+ cap , err := PipelineToCapability (pipeline )
217
+ if err != nil {
218
+ return err
219
+ }
220
+ _ , hasCap := n .Capabilities .constraints .perCapability [cap ]
221
+ if hasCap {
222
+ _ , hasModel := n .Capabilities .constraints .perCapability [cap ].Models [modelID ]
223
+ if hasModel {
224
+ n .Capabilities .mutex .Lock ()
225
+ defer n .Capabilities .mutex .Unlock ()
226
+ n .Capabilities .constraints .perCapability [cap ].Models [modelID ].Capacity += 1
227
+
228
+ return nil
229
+ }
230
+ return fmt .Errorf ("failed to release AI capability capacity, model does not exist pipeline=%v modelID=%v" , pipeline , modelID )
231
+ }
232
+ return fmt .Errorf ("failed to release AI capability capacity, pipeline does not exist pipeline=%v modelID=%v" , pipeline , modelID )
233
+ }
0 commit comments