Apache Kafka應用程序中的機器學習和實時分析(第二部分)

在優銳課的java學習分享中,這篇文章探討了構建ML基礎結構的特定部分:在Kafka應用程序中部署分析模型以進行實時預測。

文章的第一部分在這啦,記得先看哦,不然看不懂哈,更有連貫性。

Apache Kafka應用程序中的機器學習和實時分析(第一部分)

嵌入式模型的流處理

除了使用模型服務器和RPC通信之外,你還可以將模型直接嵌入到Kafka應用程序中。 這可以是利用Kafka Streams或KSQL的Kafka本機流處理應用程序,也可以使用Java,Scala,Python或Go之類的Kafka客戶端API。

在這種情況下,不依賴於外部模型服務器。 該模型已在應用程序中加載,例如使用Kafka Streams應用程序中的TensorFlow Java API:
同樣,實現Kafka應用程序很簡單。 以下是將TensorFlow模型嵌入到Kafka Streams應用程序中以進行實時預測的代碼段:
1.導入Kafka和TensorFlow API:
Java

import org.apache.kafka.streams.KafkaStreams;
import org.apache.kafka.streams.KeyValue;
import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
import org.apache.kafka.streams.kstream.KStream;
import org.deeplearning4j.nn.modelimport.keras.KerasModelImport;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;

2.從數據存儲區(例如,Amazon S3鏈接)或內存(例如,從Kafka主題接收)中加載TensorFlow模型:
Java

// Step 1: Load Keras TensorFlow Model using DeepLearning4J API
String simpleMlp = new ClassPathResource("generatedModels/Keras/simple_mlp.h5").getFile().getPath();
System.out.println(simpleMlp.toString());
MultiLayerNetwork model = KerasModelImport.importKerasSequentialModelAndWeights(simpleMlp);

3.配置Kafka Streams應用程序:
Java

// Configure Kafka Streams Application
Properties streamsConfiguration = new Properties();
streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "kafka-streams-tensorflow-keras-integration-test");
streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
// Specify default (de)serializers for record keys and for record values
streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());

4.將TensorFlow模型應用於流數據:
Java

final KStream<String, String> inputEvents = builder.stream(inputTopic);
inputEvents.foreach((key, value) -> {
// Transform input values (list of Strings) to expected DL4J parameters (two Integer values):
String[] valuesAsArray = value.split(",");
INDArray input = Nd4j.create(Integer.parseInt(valuesAsArray[0]), Integer.parseInt(valuesAsArray[1]));
// Model inference in real time:
output = model.output(input);
prediction = output.toString();
});

5.啓動Kafka應用程序:
Java

final KafkaStreams streams = new TestKafkaStreams(builder.build(), streamsConfiguration);
streams.cleanUp();
streams.start();

你甚至可以使用衆所周知的測試庫編寫單元測試,如使用JUnit和Kafka Streams測試庫的單元測試的示例所示。

以下是使用KSQL用戶定義函數(UDF)進行模型部署的示例:

你所需要做的就是實現KSQL UDF Java接口,然後將UDF部署到KSQL服務器。 先前的博客文章中詳細描述瞭如何構建自己的KSQL UDF。 使用這種方法,最終用戶可以編寫SQL查詢以實時應用分析模型。

應將哪些模型直接嵌入到應用程序中?

並非每種模型都適合嵌入到應用程序中。 在決定嵌入是否有意義時應考慮的因素包括:
模型性能:越快越好
模型二進制格式:最好是編譯的Java字節碼
型號大小:較少的MB和較少的內存是首選
模型服務器功能:開箱即用,自己構建或不需要

用Python代碼編寫的模型比較慢,因爲它是一種動態語言,必須在運行時解釋許多變量和命令。

H2O Java類(例如決策樹)執行速度非常快,通常只需幾微秒。

小型TensorFlow Protobuf神經網絡,只需幾個MB或更少的負載即可快速完成。

擁有100 MB或更多內存的大型TensorFlow Protobuf神經網絡需要大量內存,並且執行速度相對較慢。

基於標準的模型(例如,基於PMML或ONNX的XML / JSON)包括模型處理(例如數據預處理)以外的其他步驟。 使用這些標準通常會帶來組織挑戰和技術限制/約束,並且性能通常比TensorFlow的SavedModel等本地序列化模型差。

最終,是否應該將模型直接嵌入到你的應用程序中取決於模型本身,硬件基礎結構以及項目的需求。

在Kafka應用程序中重建模型服務器的功能並不困難

將模型嵌入到應用程序中意味着你沒有開箱即用的模型服務器功能。 你將必須自己實現它們。 問自己的第一個問題是:我需要模型服務器的功能嗎? 我需要動態更新模型嗎? 那版本控制呢? A / B測試? 金絲雀?
好消息是實現這些功能並不難。 根據你的要求和工具集,你可以:

啓動新版本的應用程序(例如Kubernetes窗格)
通過Kafka主題發送和使用模型或權重
通過API(例如TensorFlow Java API)動態加載新版本
利用服務網格(例如Envoy,Linkerd或Istio)而不是用於A / B測試,綠色/藍色部署,黑暗發射等的模型服務器。

讓我們評估一下在Kafka應用程序中利用分析模型的兩種方法之間的權衡。

模型服務器與嵌入模型的權衡

你可以將分析模型部署到模型服務器中並使用RPC通信,也可以將它們直接嵌入到應用程序中。 沒有最佳選擇,因爲它取決於你的基礎結構,要求和功能。

爲什麼將模型服務器和RPC與事件流應用程序一起使用?

與現有技術和組織流程的簡單集成
更容易理解,如果你來自非事件流世界
以後可以遷移到真實流
內置模型管理功能,可用於不同模型,版本控制和A / B測試
內置監控

爲什麼將模型嵌入事件流應用程序?

藉助本地推理實現更好的延遲,而無需進行遠程呼叫
脫機推斷(設備,邊緣處理等)
Kafka Streams應用程序的可用性,可伸縮性和延遲/吞吐量與RPC接口的SLA之間沒有耦合
無副作用(例如在發生故障的情況下)-卡夫卡處理涵蓋了所有內容(例如僅發生一次)

兩種選擇各有優缺點,根據情況在不同情況下建議使用。

使用Kubernetes進行雲原生模型部署

在雲原生基礎架構中,有可能獲得兩種方法的好處。 讓我們使用Kubernetes作爲我們的雲原生環境,儘管其他雲原生技術也可以提供類似的功能。

如果將分析模型嵌入到Kafka應用程序中,則將獲得單獨的pod的所有優點,該pod具有用於流處理和模型推理的容器。 對模型服務器沒有外部依賴性。

在以下示例中,你可以使用嵌入式模型獨立地擴展Kafka Streams應用程序,啓動新版本,進行A / B測試或其他路由,並使用Envoy或Linkerd等雲原生代理執行錯誤處理:

如果你仍然想獲得模型服務器的優點和功能,則可以使用sidecar設計模式。 Kubernetes支持將具有特定任務的其他容器添加到你的Pod中。 在以下示例中,Kafka Streams應用程序部署在一個容器中,模型服務器作爲Sidecar部署在同一吊艙內的另一個容器中。

這樣就可以利用模型服務器的功能以及單個容器的健壯性和可擴展性。 它仍然具有在每個容器之間使用RPC的缺點。 通過將兩個容器部署在同一容器中,可以最大程度地減少等待時間和潛在的錯誤。

邊緣模型部署

模型並不總是部署在雲或數據中心中。 在某些情況下,模型會部署在邊緣。 邊緣部署可能意味着:

邊緣數據中心或邊緣設備/機器
邊緣有一個Kafka集羣,一個Kafka經紀人或一個Kafka客戶
功能強大的客戶端(例如KSQL或Java)或輕量級客戶端(例如C或JavaScript)
嵌入式或RPC模型推斷
本地或遠程培訓
法律和合規性影響

對於某些電信提供商來說,邊緣計算的定義是超低延遲,且端到端通信時間不到100毫秒。 這是通過諸如開源雲基礎架構軟件堆棧StarlingX之類的框架實現的,該框架需要完整的OpenStack和Kubernetes集羣以及對象存儲。 對於其他人來說,edge表示你在其中部署非常小的輕量級C應用程序和模型的移動設備,輕量級板或傳感器。

從卡夫卡的角度來看,有很多選擇。 你可以使用librdkafka(本機Kafka C / C ++客戶端庫)完全構建輕量級的邊緣應用程序,該庫由Confluent完全支持。 還可以使用JavaScript並利用REST代理或WebSocket集成進行Kafka通信,將模型嵌入移動應用程序中。

Kafka的技術獨立模型部署

在過程和技術上,模型部署可以與模型訓練完全分開。部署基礎架構可以處理不同的模型,甚至可以使用不同的機器學習框架訓練模型。 Kafka還爲構建機器學習監控提供了良好的基礎,包括基礎設施的技術監控和特定於模型的監控,例如性能或模型準確性。

無論你是否要使用Kafka實施所有功能(包括數據集成,預處理,模型部署和監視),或者是否僅使用Kafka客戶端將模型嵌入到真實模型中,Kafka都是機器學習基礎設施的理想選擇和補充工具時間的Kafka客戶端(與數據預處理和模型訓練完全分開)。

對於模型部署,存在兩種選擇:模型服務器(RPC)和嵌入式模型。瞭解每種方法的利弊將有助於你爲項目做出正確的決定。實際上,將分析模型嵌入到Kafka應用程序中很簡單,而且非常有用。

喜歡這篇文章的可以點個贊,歡迎大家留言評論,記得關注我,每天持續更新技術乾貨、職場趣事、海量面試資料等等
如果你對java技術很感興趣也可以加入我的java學習羣 V–(ddmsiqi)來交流學習,裏面都是同行,驗證【CSDN2】有資源共享。
不要再用"沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章