Creazione e salvataggio di un modello con l'SDK Python OCI

Creare un modello con Python e salvarlo direttamente nel catalogo modelli.

Per creare e salvare un modello, è innanzitutto necessario creare l'artifact modello.

Si consiglia di creare e salvare i modelli nel catalogo modelli a livello di programmazione, utilizzando ADS o l'SDK Python OCI.

Importante

  1. (Facoltativo) Aggiornare l'SDK Python OCI con pip install oci –upgrade.
  2. Salvare un oggetto modello su disco. È possibile utilizzare vari strumenti per salvare un modello (Joblib, cloudpickle, pickle, ONNX e così via). Si consiglia di salvare un oggetto modello nella directory di livello superiore dell'artifact modello e allo stesso livello dei file score.py e runtime.yaml.
  3. Modificare il file score.py per definire le funzioni load_model() e predict(). Modificare il corpo di entrambe le funzioni per supportare il modello nel modo seguente:
    load_model()

    Legge il file modello su disco e restituisce l'oggetto valutatore. Assicurarsi di utilizzare la stessa libreria per serializzare e deserializzare l'oggetto modello.

    predict()

    Contiene due parametri, data e model. Il parametro obbligatorio è data, che rappresenta un payload del data set mentre il modello è un parametro facoltativo. Per impostazione predefinita, model è l'oggetto restituito da load_model(). Assicurarsi che il tipo di dati del parametro dati corrisponda al formato del payload previsto con la distribuzione del modello.

    Per impostazione predefinita, la distribuzione del modello presuppone che data sia un payload JSON (MIME type application/json). La funzione predict() converte il payload JSON in un formato di dati dell'oggetto modello. Ad esempio, un dataframe Pandas o un array Numpy quando si tratta del formato dati supportato dall'oggetto modello. Il corpo di predict() può includere trasformazioni dei dati e altri task di manipolazione dei dati prima di eseguire una previsione del modello.

    Altre cose da considerare:

    • Impossibile modificare le firme funzione di load_model() e predict(). È possibile modificare solo il corpo di queste funzioni per personalizzarle.
    • Se sono disponibili nel file artifact, è possibile importare qualsiasi modulo Python personalizzato utilizzando score.py o come parte dell'ambiente Conda utilizzato per scopi di inferenza.
    • È possibile salvare più oggetti modello nell'artifact. È possibile caricare in memoria più oggetti valutatore per eseguire una valutazione dell'insieme. In questo caso, load_model() può restituire un array di oggetti modello elaborati da predict().

  4. (Facoltativo) Eseguire il test della funzione score.predict().

    Si consiglia di eseguire il test della funzione predict() nell'ambiente locale prima di salvare il modello nel catalogo modelli. Il seguente frammento di codice mostra come passare un payload JSON per prevedere che imiti il funzionamento del modello distribuito mediante la distribuzione del modello. Questo è un buon modo per garantire che l'oggetto modello venga letto da load_model(). Inoltre, le previsioni restituite dai modelli sono corrette e nel formato previsto. Se si esegue questo snippet di codice in una sessione notebook, si ottiene anche l'output di tutti i logger definiti in score.py nella cella di output.

    import sys
    from json import dumps
     
    # The local path to your model artifact directory is added to the Python path.
    # replace <your-model-artifact-path>
    sys.path.insert(0, f"<your-model-artifact-path>")
     
    # importing load_model() and predict() that are defined in score.py
    from score import load_model, predict
     
    # Loading the model to memory
    _ = load_model()
     
    # Take a sample of your training or validation dataset and store it as data.
    # Making predictions on a JSON string object (dumps(data)). Here we assume
    # that predict() is taking data in JSON format
    predictions_test = predict(dumps(data), _)
    # Compare the predictions captured in predictions_test with what you expect for data:
    predictions_test
  5. Modificare il file runtime.yaml.

    Questo file fornisce un riferimento all'ambiente Conda che si desidera utilizzare per l'ambiente runtime per la distribuzione del modello. Per una distribuzione modello, il file deve contenere almeno i campi riportati di seguito.

    MODEL_ARTIFACT_VERSION: '3.0'
    MODEL_DEPLOYMENT:
      INFERENCE_CONDA_ENV:
        INFERENCE_ENV_SLUG: <the-slugname> # for example mlcpuv1 see: https://docs.oracle.com/en-us/iaas/Content/data-science/using/conda-gml-fam.htm
        INFERENCE_ENV_TYPE: <env-type> # can either be "published" or "data_science"
        INFERENCE_ENV_PATH: <conda-path-on-object-storage>
        INFERENCE_PYTHON_VERSION: <python-version-of-conda-environment>

    Di seguito è riportato un esempio di file runtime.yaml. Il data scientist sta selezionando l'ambiente Conda TensorFlow.

    MODEL_ARTIFACT_VERSION: '3.0'
    MODEL_DEPLOYMENT:
      INFERENCE_CONDA_ENV:
        INFERENCE_ENV_SLUG: tensorflow23_p37_cpu_v1
        INFERENCE_ENV_TYPE: data_science
        INFERENCE_ENV_PATH: oci://service-conda-packs@id19sfcrra6z/service_pack/cpu/Tensorflow for CPU Python 3.7/1.0/tensorflow23_p37_cpu_v1
        INFERENCE_PYTHON_VERSION: '3.7'
  6. (Facoltativo) (Consigliato) Prima di salvare un modello nel catalogo, è consigliabile eseguire una serie di test di introduzione sull'artifact del modello.

    Lo scopo di questi test è quello di identificare eventuali errori convalidando i file score.py e runtime.yaml con un set di controlli per garantire che abbiano la sintassi, i parametri e le versioni corrette. I test di introspezione vengono definiti come parte del modello di codice artifact modello.

    1. Per eseguire i test è richiesta una versione 3.5 o successiva di Python. Prima di eseguire i test in locale sul computer, è necessario installare le librerie Python pyyaml e requests. Questa installazione è un'operazione una tantum.

      Andare alla directory degli artifact. Eseguire il comando riportato di seguito per installare le dipendenze di terze parti necessarie.

      python3 -m pip install --user -r artifact-introspection-test/requirements.txt
    2. Eseguire i test a livello locale sostituendo <artifact-directory> con il percorso della directory artifact del modello:
      python3 artifact-introspection-test/model_artifact_validate.py --artifact <artifact-path>
    1. Controllare i risultati del test.

      Lo script model_artifact_validate.py genera due file di output nella directory di livello superiore degli artifact del modello:

      • test_json_output.json

      • test_html_output.html

      È possibile aprire entrambi i file per esaminare gli errori. Se si apre il file HTML, i messaggi di errore vengono visualizzati sullo sfondo rosso.

    2. Ripetere i passi da 2 a 6 finché tutti i test non verranno eseguiti correttamente. Dopo la corretta esecuzione dei test, l'artifact modello è pronto per essere salvato nel catalogo modelli.
  7. Crea e salva il modello nel catalogo modelli utilizzando l'SDK OCI con un file di configurazione OCI, che fa parte della gestione degli accessi all'SDK standard.
    1. Inizializzare il client con:
      # Create a default config using DEFAULT profile in default location
      # Refer to
      # https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm#SDK_and_CLI_Configuration_File
      # for more info
       
      import oci
      from oci.data_science.models import CreateModelDetails, Metadata, CreateModelProvenanceDetails, UpdateModelDetails, UpdateModelProvenanceDetails
      config = oci.config.from_file()
      data_science_client = oci.data_science.DataScienceClient(config=config)
       
      # Initialize service client with user principal (config file)
      config = oci.config.from_file()
      data_science_client = oci.data_science.DataScienceClient(config=config)
       
      # Alternatively initialize service client with resource principal (for example in a notebook session)
      # auth = oci.auth.signers.get_resource_principals_signer()
      # data_science_client = oci.data_science.DataScienceClient({}, signer=auth)
    2. (Facoltativo) Documentare la provenienza del modello.

      Ad esempio:

      provenance_details = CreateModelProvenanceDetails(repository_url="EXAMPLE-repositoryUrl-Value",
                                                        git_branch="EXAMPLE-gitBranch-Value",
                                                        git_commit="EXAMPLE-gitCommit-Value",
                                                        script_dir="EXAMPLE-scriptDir-Value",
                                                        # OCID of the ML job Run or Notebook session on which this model was
                                                        # trained
                                                        training_id="<Notebooksession or ML Job Run OCID>"
                                                        )
    3. (Facoltativo) Documentare la tassonomia del modello.

      Ad esempio:

      # create the list of defined metadata around model taxonomy:
      defined_metadata_list = [
          Metadata(key="UseCaseType", value="image_classification"),
          Metadata(key="Framework", value="keras"),
          Metadata(key="FrameworkVersion", value="0.2.0"),
          Metadata(key="Algorithm",value="ResNet"),
          Metadata(key="hyperparameters",value="{\"max_depth\":\"5\",\"learning_rate\":\"0.08\",\"objective\":\"gradient descent\"}")
      ]
    4. (Facoltativo) Aggiungere i metadati personalizzati (attributi).

      Ad esempio:

      # Adding your own custom metadata:
      custom_metadata_list = [
          Metadata(key="Image Accuracy Limit", value="70-90%", category="Performance",
                   description="Performance accuracy accepted"),
          Metadata(key="Pre-trained environment",
                   value="https://blog.floydhub.com/guide-to-hyperparameters-search-for-deep-learning-models/",
                   category="Training environment", description="Environment link for pre-trained model"),
          Metadata(key="Image Sourcing", value="https://lionbridge.ai/services/image-data/", category="other",
                   description="Source for image training data")
      ]
    5. (Facoltativo) Documentare le definizioni dello schema dei dati di input e di output del modello.
      Importante

      La definizione dello schema sia per il vettore della funzione di input che per le previsioni del modello viene utilizzata a scopo di documentazione. Questa linea guida si applica solo ai set di dati in formato tabulare.

      Ad esempio:

      import json
      from json import load
      # Declare input/output schema for our model - this is optional
      # It must be a valid json or yaml string
      # Schema like model artifact is immutable hence it is allowed only at the model creation time and cannot be updated
      # Schema json sample in appendix
      input_schema = load(open('SR_input_schema.json','rb'))
      input_schema_str= json.dumps(input_schema)
      output_schema = load(open('SR_output_schema.json','rb'))
      output_schema_str= json.dumps(output_schema)
    6. (Facoltativo) Documentare i risultati del test di introspezione.
      Ad esempio:
      # Provide the introspection test results
       
      test_results = load(open('test_json_output.json','rb'))
      test_results_str = json.dumps(test_results)
      defined_metadata_list.extend([Metadata(key="ArtifactTestResults", value=test_results_str)])
    7. (Facoltativo) Impostare il valore di timeout del client per evitare un errore di timeout del servizio Data Science durante il salvataggio degli artifact di modelli di grandi dimensioni:
      import oci
       
      config = oci.config.from_file()
      data_science_client = oci.data_science.DataScienceClient(config=config)
      # Change the timeout value to 1800 sec (30 mins)
      data_science_client.base_client.timeout =  30 * 60
    8. Creare un archivio zip dell'artifact modello:
      import zipfile
      import os
           
      def zipdir(target_zip_path, ziph, source_artifact_directory):
          ''' Creates a zip archive of a model artifact directory.
           
          Parameters:
           
          - target_zip_path: the path where you want to store the zip archive of your artifact
          - ziph: a zipfile.ZipFile object
          - source_artifact_directory: the path to the artifact directory.
       
          Returns a zip archive in the target_zip_path you specify.    
       
          '''
          for root, dirs, files in os.walk(source_artifact_directory):
              for file in files:
                  ziph.write(os.path.join(root, file),
                             os.path.relpath(os.path.join(root,file),
                                             os.path.join(target_zip_path,'.')))
             
      zipf = zipfile.ZipFile('<relpath-to-artifact-directory>.zip', 'w', zipfile.zip_DEFLATED)
      zipdir('.', zipf, "<relpath-to-artifact-directory>")
      zipf.close()
    9. Creare (salvare) il modello nel catalogo modelli:
      # creating a model details object:
      model_details = CreateModelDetails(
          compartment_id='<compartment-ocid-of-model>',
          project_id='<project-ocid>',
          display_name='<display-name-of-model>',
          description='<description-of-model>',
          custom_metadata_list=custom_metadata_list,
          defined_metadata_list=defined_metadata_list,
          input_schema=input_schema_str,
          output_schema=output_schema_str)
       
      # creating the model object:
      model = data_science_client.create_model(model_details)
      # adding the provenance:
      data_science_client.create_model_provenance(model.data.id, provenance_details)
      # adding the artifact:
      with open('<relpath-to-artifact-directory>.zip','rb') as artifact_file:
          artifact_bytes = artifact_file.read()
          data_science_client.create_model_artifact(model.data.id, artifact_bytes, content_disposition='attachment; filename="<relpath-to-artifact-directory>.zip"')
  8. A questo punto è possibile visualizzare i dettagli del modello e visualizzare le informazioni del modello, inclusi eventuali metadati facoltativi definiti.

Utilizzare questi file di codice di esempio ed esempio di notebook per facilitare ulteriormente la progettazione di un'area di memorizzazione dei modelli.