撰寫可部署的 Python 函數

瞭解如何撰寫 Python 函數,然後將它儲存為容許部署模型的資產。

如需可部署函數的一般需求清單,請參閱 可部署函數的一般需求。 如需函數部署期間所發生情況的相關資訊,請參閱 函數部署程序

可部署函數的一般需求

若要順利部署,函數必須符合下列需求:

  • 匯入時的 Python 函數檔必須具有 score 函數物件作為其範圍的一部分。 請參閱 評分功能需求
  • 評分輸入有效負載必須符合 評分輸入需求 中列出的需求
  • 預期作為 score 輸出的輸出有效負載必須包括狀態碼 200 的 score_response 變數綱目。 請注意, prediction 參數 (以 JSON 物件陣列作為其值) 在 score 輸出中是必要的。
  • 當您使用 Python 用戶端來儲存包含外部函數參照的 Python 函數時,只會儲存外部函數 (包括其巢狀函數) 範圍內的程式碼。 因此,外部函數範圍之外的程式碼將不會儲存,因此當您部署函數時將無法使用。

評分功能需求

  • 有兩種方式可以新增 score 函數物件:
    • 明確,依使用者
    • 隱含地,透過用來將 Python 函數儲存為 Watson Machine Learning 儲存庫中資產的方法
  • score 函數必須接受單一 JSON 輸入參數。
  • score 函數必須傳回 JSON 序列化物件(例如:字典或清單)

評分輸入需求

  • 評分輸入有效負載必須包含名稱為 values的陣列,如下列範例綱目所示。

    {"input_data": [{
       "values": [["Hello world!"]]
                   }]
    }
    
    附註:
    -` input_data ` 參數在有效負載中是必要的。
    -` input_data ` 參數也可以包括其他名稱/值配對。
  • 評分輸入有效負載必須作為 score的輸入參數值傳遞。 這樣您可以確保在 score內相應地處理 score 輸入參數的值。

  • 評分輸入有效負載必須符合所涉及 Python 函數的輸入需求。

  • 評分輸入有效負載必須包含符合 範例輸入資料綱目的陣列。

輸入資料綱目範例

 {"input_data": [{
    "values": [["Hello world!"]]
                }]
 }

範例 Python 程式碼

#wml_python_function
def my_deployable_function():

    def score( payload ):

        message_from_input_payload = payload.get("input_data")[0].get("values")[0][0]
        response_message = "Received message - {0}".format(message_from_input_payload)

        # Score using the pre-defined model
        score_response = {
            'predictions': [{'fields': ['Response_message_field'],
                             'values': [[response_message]]
                            }]
        }
        return score_response

    return score

score = my_deployable_function()

您可以測試您的功能,如下所示:
input_data = { "input_data": [{ "fields": [ "message" ],
                                "values": [[ "Hello world!" ]]
                               }
                              ]
             }
function_result = score( input_data )
print( function_result )

它會傳回訊息 "Hello world!"。

函數部署程序

Watson Machine Learning 引擎會使用 import 陳述式將函數資產的 Python 程式碼載入為 Python 模組。 這表示程式碼只會執行一次 (在部署函數時,或每次重新啟動對應的 Pod 時)。 然後會在每個預測要求中呼叫由「函數」資產定義的 score 函數。

處理可部署的函數

使用下列其中一種方法來建立可部署的 Python 函數:

透過 REST API 建立可部署的函數

對於 REST API ,因為 Python 函數直接透過檔案上傳,所以該檔案必須已包含 score 函數。 任何一次匯入都可以在檔案的廣域範圍內完成,稍後在 score 函數內使用需要執行的任何一次匯入。 當此檔案部署為 Python 函數時,廣域範圍中可用的一次性匯入會在部署期間執行,稍後只會與每個預測要求一起重複使用。

重要事項:

函數保存檔必須是 .gz 檔。

範例 score 函數檔:

Score function.py
---------------------
def score(input_data):
    return {'predictions': [{'values': [['Just a test']]}]}

具有一次性匯入的 score 函數範例:

import subprocess
subprocess.check_output('pip install gensim --user', shell=True)
import gensim

def score(input_data):
    return {'predictions': [{'fields': ['gensim_version'], 'values': [[gensim.__version__]]}]}

透過 Python 用戶端建立可部署函數

若要將 Python 函數持續保存為資產, Python 用戶端會使用 wml_client.repository.store_function 方法。 您可以透過兩種方式來執行該動作:

透過包含 Python 函數的檔案來持續保存函數

此方法與透過 REST API 持續保存 Python 函數檔相同 (score 必須定義在 Python 原始檔的範圍中)。 如需詳細資料,請參閱 透過 REST API 建立可部署的函數

重要事項:

當您呼叫 wml_client.repository.store_function 方法時,請傳遞檔名作為第一個引數。

透過函數物件持續保存函數

您可以使用名為 score的巢狀函數來建立 Python Closures ,以持續保存 Python 函數物件。 呼叫時儲存為函數物件的外部函數會傳回 score 函數。 此 score 函數必須符合 可部署函數的一般需求中列出的需求。 在此情況下,必須在外部巢狀函數中新增任何一次匯入及起始設定邏輯,以便在部署期間執行它們,並在 score 函數內使用它們。 必須在巢狀 score 函數內新增 prediction 要求期間所需的任何循環邏輯。

使用 Python 用戶端儲存 Python 函數範例:

def my_deployable_function():

    import subprocess
    subprocess.check_output('pip install gensim', shell=True)
    import gensim

    def score(input_data):
        import
        message_from_input_payload = payload.get("input_data")[0].get("values")[0][0]
        response_message = "Received message - {0}".format(message_from_input_payload)

        # Score using the pre-defined model
        score_response = {
            'predictions': [{'fields': ['Response_message_field', 'installed_lib_version'],
                             'values': [[response_message, gensim.__version__]]
                            }]
        }
        return score_response

    return score

function_meta = {
    client.repository.FunctionMetaNames.NAME:"test_function",
    client.repository.FunctionMetaNames.SOFTWARE_SPEC_ID: sw_spec_id
}
func_details = client.repository.store_function(my_deployable_function, function_meta)

在此實務範例中, Python 函數會負責建立 Python 檔案,其中包含 score 函數,並將函數檔案持續保存為 Watson Machine Learning 儲存庫中的資產:

score = my_deployable_function()

進一步瞭解

上層主題: 部署 Python 函數