雲栖号資訊:【 點選檢視更多行業資訊】
在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!
在看到最近新推出的 GitHub Actions 後,我的第一個想法是建立一個簡單的示例項目,在這個項目中,我們“部署”一個使用了這個新特性的機器學習模型。當然,這不是一個“真正的部署”,但是可用此模型在存儲庫中測試你的模型,而不需要任何額外的編碼。
GitHub Actions 是一個用于建構、測試和部署的自動化工具。舉個例子快速了解下它是什麼:每次你建立一個 Pull Request(帶有某個标簽)時,都會觸發新的應用程式建構,然後它可以向進階開發人員發送消息,讓他們快速檢視代碼。
項目位址:
https://github.com/gaborvecsei/Machine-Learning-Inference-With-GitHub-Actions我們将建立什麼?
在存儲庫上建立一個自定義操作和自動化工作流,你可以在其中使用經過訓練的模型,并在某個問題有了新評論時觸發它。你還可以找到模型訓練和推理代碼。我想要超級硬核,是以我選擇了 Iris 資料集和随機森林分類器。這個樹內建模型經過訓練,可以根據萼片和花瓣的長度和寬度來識别花朵。
這個模型的訓練是在 Jupyter Notebook 上完成的。這些代碼訓練并序列化我們将用于預測的模型。當問題收到評論時,GitHub Actions 工作流将被觸發。如果評論包含字首 /predict,那麼我們就開始解析評論,然後我們做一個預測并構造一個回複。最後一步,該消息由機器人在相同的問題下發回給使用者。為了把事情做得更好,整個自定義操作将在 Docker 容器中運作。

我們将找出工作流中的步驟,并為某些步驟建立單獨的操作。一個工作流可以包含多個操作,但是在這個項目中,我們将使用單個操作。
建立一個操作
第一步,我們應該在名為 action.yaml 的根檔案夾中建立操作。在這裡,我們可以描述 inputs、outputs 和運作環境。
name: 'Prediction GitHub Action Test'
description: 'This is a sample with which you can run inference on a ML model with a toy dataset'
inputs:
issue_comment_body:
required: true
description: 'This is the Github issue comment message'
issue_number:
required: true
description: 'Number of the Github issue'
issue_user:
required: true
description: 'This user send the comment'
outputs:
issue_comment_reply:
description: 'Reply to the request'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.issue_comment_body }}
- ${{ inputs.issue_number }}
- ${{ inputs.issue_user }}
從上到下,你可以看到定義好的 3 個輸入和 1 個輸出。最後,runs 鍵描述了我們的代碼将要在其中運作的環境。這是一個 Docker 容器,其輸入将作為參數傳入。是以,容器的入口點應該按照定義的順序接受這 3 個參數。
容器
如果我們仔細檢視 Dockerfile,就可以看到我們的運作環境是如何建構的。首先,我們安裝所有 Python 需要的東西。然後複制 entrypoint.sh 并使其可執行,這樣它就可以在容器内運作了。最後,序列化的 sklearn 模型檔案被複制到容器中,這樣,我們就可以使用它來進行預測。(在真實的場景中,不應該将模型檔案存儲在存儲庫中。這隻是為了可以快速示範。)
FROM python:3.6
# Install python requirements
COPY requirements.txt /requirements.txt
RUN pip install -r /requirements.txt
# Setup Docker entrypoint script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Copy the trained model
COPY random_forest_model.pkl /random_forest_model.pkl
ENTRYPOINT ["/entrypoint.sh"]
定義工作流
沒有工作流就不能使用操作。它定義了你希望在管道中采取的不同步驟。
name: Demo
on: [issue_comment]
jobs:
my_first_job:
runs-on: ubuntu-latest
name: Just a simple demo job
steps:
- name: Checkout
uses: actions/checkout@master
- name: See full payload (for debugging)
env:
PAYLOAD: ${{ toJSON(github.event) }}
run: echo "FULL PAYLOAD:\n${PAYLOAD}\n"
- name: Run the container and make a prediction
if: startsWith(github.event.comment.body, '/predict')
uses: ./
id: make_prediction
with:
issue_comment_body: ${{ github.event.comment.body }}
issue_number: ${{ github.event.issue.number }}
issue_user: ${{ github.event.comment.user.login }}
- name: Print the output from the container(for debugging)
run: echo "The reply message is ${{steps.make_prediction.outputs.issue_comment_reply}}"
- name: Send reply to issue for user
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash issue_comment.sh "steps.makeprediction.outputs.issuecommentreply""{{ github.event.issue.number }}"
首先,on: [issue_comment] 定義了我希望在接收到某個問題的評論(任何人提出的任何問題)時觸發這個流。然後,我通過 runs-on: ubuntu-latest 定義了運作的 VM 類型(它可以是自托管的,也可以是由 GitHub 提供的)。接下來是有趣的部分,我之前提到的步驟。
- 簽出步驟:在這個步驟中,我們将移到存儲庫中所需的分支上(這也是一個 github 操作)。
- 檢視有效負載:我在這裡把它用于調試。在問題下收到評論後,它顯示整個有效負載,包括這個容器、評論、問題編号、留下評論的使用者等等。
- 做出預測:這是我們的自定義動作。代碼行 if: startsWith(github.event.comment.body,’/predict’) 確定隻有在出現有效的預測請求時才運作這個步驟(包含字首 /predict)。你可以看到,輸入是在 with 關鍵字下定義的,而值是通過它們的鍵(如 github.event.comment.body)從負載中添加的。
- 列印應答:構造的應答被回顯到日志。它使用前面的步驟中定義的輸出:steps.make_prediction.output .issue_comment_reply。
- 發送應答:建立的應答中包含預測,将使用腳本 issue_comments .sh 作為應答發送。
每個步驟都在指定的運作器 ubuntu-latest 上運作,但是我們的操作在建立的容器中運作。此容器是在工作流被觸發時建構的。(我本來可以緩存它,這樣每次流運作時就可以使用以前建構的映像,但是我還是懶得将它添加到這個示例中)。
做出預測
有一件事我沒有談到:預測是如何做出的?你可以通過檢視 main.py 腳本輕松地解決這個問題。
model = load_model("/random_forest_model.pkl")
try:
sepal_length, sepal_width, petal_length, petal_width = parse_comment_input(args.issue_comment_body)
predicted_class_id = make_prediction(model, sepal_length, sepal_width, petal_length, petal_width)
predicted_class_name = map_class_id_to_name(predicted_class_id)
reply_message = f"Hey @{args.issue_user}!<br>This was your input: {args.issue_comment_body}.<br>The prediction: **{predicted_class_name}**"
except Exception as e:
reply_message = f"Hey @{args.issue_user}! There was a problem with your input. The error: {e}"
print(f"::set-output name=issue_comment_reply::{reply_message}")
看到上面的内容,可能你就會覺得這太簡單了:輸入、資料集、模型、模式存儲、如何處理請求等等。例如,對于圖像輸入,你可以從一個 base64 字元串解碼,然後通過存儲在 GitLFS 中的深度學習模型運作它。那麼,就動手實際操作下吧。
【雲栖号線上課堂】每天都有産品技術專家分享!
課程位址:
https://yqh.aliyun.com/zhibo立即加入社群,與專家面對面,及時了解課程最新動态!
【雲栖号線上課堂 社群】
https://c.tb.cn/F3.Z8gvnK
原文釋出時間:2020-03-31
本文作者:Gábor Vecsei
本文來自:“
InfoQ”,了解相關資訊可以關注“
”