Snelle machine learning met TensorFlow en Kubernetes
Het trainen van machine learning-modellen kan zeer tijdrovend zijn als je niet over de juiste ondersteunende hardware beschikt. Zo moet je bij neurale netwerken de bijdrage van elke neuron aan de totale fout berekenen tijdens de trainingsstap. Dit kan oplopen tot duizenden berekeningen per stap. Complexe modellen en uitgebreide gegevenssets kunnen een lang trainingsproces vereisen. De prestaties van applicaties kunnen vertragen door het op schaal evalueren van dergelijke modellen. Om nog maar te zwijgen over de hyperparameters die je moet afstemmen en het herhaaldelijk opnieuw opstarten van het proces.
Ik wil in deze blog bespreken hoe je deze problemen kunt overwinnen door je resources optimaal te benutten. Ik wil het specifiek hebben over TensorFlow, een raamwerk dat is ontwikkeld voor parallel computing en Kubernetes, een platform dat kan worden op- en afgeschaald voor applicatiegebruik.
TensorFlow
TensorFlow is een open source-bibliotheek voor het bouwen en trainen van machine learning-modellen. Het is van oorsprong een project van Google en is heel succesvol op het gebied van AI. Het is verkrijgbaar in meerdere abstractieniveaus, zodat vooraf gedefinieerde machine learning-modellen eenvoudig zijn te configureren. TensorFlow is ontwikkeld om te worden uitgevoerd op gedistribueerde systemen. De benodigde berekeningen kunnen parallel worden uitgevoerd op meerdere apparaten via onderliggende gegevensstroomgrafieken. Deze vertegenwoordigen een reeks wiskundige vergelijkingen, met multidimensionale array-weergaven (tensors) bij de randen. DeepMind heeft dit vermogen gebruikt om AlphaGo Zero te creëren, met 64 GPU-workers en 19 CPU-parameterservers om binnen 3 dagen 4,9 miljoen keer GO tegen zichzelf te spelen.
Kubernetes
Kubernetes is ook een project van Google en is een opensourceplatform om applicaties in containers op schaal te beheren. Je kunt met Kubernetes eenvoudig meer instance-nodes toevoegen en de beschikbare hardware optimaler benutten. Kubernetes is vergelijkbaar met kassa's in de supermarkt. Als er een lange rij klanten staat te wachten, dan wordt er snel een nieuwe kassa geopend om een deel van die klanten te helpen. Dit betekent in de praktijk dat Kubernetes (de kassa) een virtuele machine is die een service uitvoert en dat klanten de consumenten zijn van die service.
De kracht van Kubernetes is het gebruiksgemak. Er hoeven geen nieuwe instances te worden gemaakt en toegevoegd aan de load balancer. Dit verloopt automatisch. De nieuwe instance hoeft niet te worden gekoppeld aan bestandsopslag of netwerken, dit wordt door Kubernetes geregeld. Instances die zich niet naar behoren gedragen, worden vernietigd en er wordt direct een nieuwe geactiveerd.
Gedistribueerde training
De benodigde tijd om een model te trainen kan zoals eerder beschreven, worden verkort door parallel berekeningen uit te voeren op verschillende hardwaresystemen. Je kunt zelfs met een beperkte configuratie je trainingstijd tot een minimum beperken door deze te verdelen over meerdere apparaten. Met TensorFlow kun je CPU's, GPU's en zelfs TPU's gebruiken of Tensor Processing Unit, een chip die is ontwikkeld om TensorFlow-bewerkingen uit te voeren. Je moet een Strategy (strategie) bepalen en je model moet binnen het bereik van die strategie worden gemaakt en gecompileerd.
mirrored_strategy = tf.distribute.MirroredStrategy()
with mirrored_strategy.scope():
model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
model.compile(loss='mse', optimizer='sgd')
Met bovenstaande MirroredStrategy kun je de training verdelen over meerdere GPU's op hetzelfde systeem. Het model wordt voor elke GPU gerepliceerd en er worden voor elke replica variabele updates uitgevoerd.
Een interessantere variant op deze strategie is de MultiWorkerMirroredStrategy. Deze strategie biedt de mogelijkheid om de training te distribueren over meerdere machines (workers) die allemaal meerdere GPU's kunnen gebruiken. Kubernetes kan hierbij helpen om je machine learning te versnellen. Je kunt Kubernetes, op basis van de behoefte aan parameterservers en workers, gebruiken om meerdere servicenodes te creëren. Parameterservers bewaken de modelparameters en workers berekenen de updates voor die parameters. Je kunt de algemene bandbreedte tussen de leden van de servercluster verminderen door meer parameterservers toe te voegen. Om de configuratie uit te voeren, moet je een omgevingsvariabele TS_CONFIG instellen die de rol van elke node en de configuratie van de rest van het cluster bepaalt.
os.environ["TF_CONFIG"] = json.dumps({
'cluster': {
'worker': ['worker-0:5000', 'worker-1:5000'],
'ps': ['ps-0:5000']
},
'task': {'type': 'ps', 'index': 0}
})
Om de configuratie te vereenvoudigen is er een Github-opslagplaats met een sjabloon voor Kubernetes. Houd er rekening mee dat TS_CONFIG zelf niet wordt geconfigureerd, de content wordt als parameters doorgevoerd naar het script. Deze parameters worden gebruikt om te bepalen welke apparaten in een gedistribueerde training kunnen worden gebruikt.
cluster = tf.train.ClusterSpec({
"worker": ['worker-0:5000', 'worker-1:5000'],
"ps": ['ps-0:5000']})
server = tf.train.Server(
cluster, job_name='ps', task_index='0')
Met ClusterSpec worden de worker en parameterservers in het cluster bepaald. De waarde is hetzelfde voor alle nodes. De Server bevat de definitie van de taak van de huidige node, dus per node een andere waarde.
TensorFlow Serving
Voor gedistribueerde interferentie bevat TensorFlow een pakket om machine learning-modellen te hosten. Dit heet TensorFlow Serving en het is ontworpen om snel machine learning-modellen te configureren en beheren. Er is alleen een SavedModel-weergave voor vereist. SavedModel is een indeling om getrainde Tensorflowmodellen zodanig te trainen dat ze eenvoudig te laden en herstellen zijn. Een SavedModel kan in een map worden geserialiseerd en wordt daardoor tamelijk draagbaar en gemakkelijk te delen.
Een SavedModel is heel snel te creëren met de geïntegreerde functie save.
model_version = '1'
model_name = 'my_model'
model_path = os.path.join('/path/to/save/dir/', model_name, model_version)
model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])
model.compile(loss='mse', optimizer='sgd')
model.fit(X_train, y_train, epochs=10, validation_data=(X_valid, y_valid))
tf.saved_model.save(model, model_path)
Gebruik de SavedModel CLI om SavedModel-bestanden te controleren. Zodra deze bestanden op de juiste plek staan, kan TensorFlow Serving het in een gRPC of RESTful-interface veranderen. De Docker-afbeelding tensorflow/serving biedt het eenvoudigste pad naar een actieve server. Er zijn diverse versies van deze afbeelding, waaronder een voor GPU-gebruik. Naast de keuze voor de juiste afbeelding, hoef je alleen nog maar het pad op te geven naar de map die je zojuist hebt gemaakt en je moet je model een naam geven.
$ docker run -t --rm -p 8500:8500 -p 8501:8501 \
-v "/path/to/save/dir/my_model:/models/my_model" \
-e MODEL_NAME=my_model \
tensorflow/serving
Je kunt Kubernetes nu vanzelfsprekend gebruiken om een implementatie te creëren voor deze afbeelding en je kunt het aantal replica's automatisch op- of afschalen. Plaats er een LoadBalancer Service voor en je gebruikers worden ongemerkt naar de juiste node doorgestuurd. Interferentie vereist veel minder rekenkracht en de berekening hoeft daarom niet te worden gedistribueerd over meerdere nodes. Houd er rekening mee dat het pad naar de map 'save' ook een map 'version' bevat. TensorFlow Serving gebruikt deze conventie om de map te controleren op nieuwe versies van een SavedModel. Zodra er een nieuwe versie wordt gedetecteerd, wordt deze automatisch geladen, gereed om te leveren. Je kunt met TensorFlow Serving en Kubernetes elke belasting aan voor je classificatie-, regressie-of voorspellingsmodellen.
🚀 Takeaway
Je wint veel tijd door de benodigde berekeningen voor je machine learning-project te distribueren. Door een zeer schaalbare bibliotheek zoals TensorFlow te combineren met een flexibel platform zoals Kubernetes, kun je het gebruik van resources en tijd optimaliseren.
Je kunt zaken uiteraard nog verder versnellen als je wordt ondersteund door een Kubernetes-team of door iemand die je helpt om je machine learning-modellen af te stemmen. Wil jij je machine learning naar een hoger niveau tillen? Wij kunnen dat voor je regelen! Interesse of vragen? Stuur een e-mail naar tom.vanwemmel@aca-it.be!