Menerbitkan dan melacak alur pembelajaran mesin

BERLAKU UNTUK:SDK Python azureml v1

Artikel ini akan menunjukkan kepada Anda cara berbagi alur pembelajaran mesin dengan kolega atau pelanggan Anda.

Alur pembelajaran mesin adalah alur kerja yang dapat digunakan kembali untuk tugas pembelajaran mesin. Salah satu manfaat alur adalah peningkatan kolaborasi. Anda juga dapat membuat versi alur, yang memungkinkan pelanggan untuk menggunakan model saat ini ketika Anda sedang mengerjakan versi yang baru.

Prasyarat

Menerbitkan alur

Setelah alur aktif dan berjalan, Anda dapat menerbitkan alur sehingga alur tersebut berjalan dengan input yang berbeda. Untuk titik akhir REST dari alur yang sudah diterbitkan untuk menerima parameter, Anda harus mengonfigurasi alur Anda agar menggunakan objek PipelineParameter untuk argumen yang akan bervariasi.

  1. Untuk membuat parameter alur, gunakan objek PipelineParameter dengan nilai default.

    from azureml.pipeline.core.graph import PipelineParameter
    
    pipeline_param = PipelineParameter(
      name="pipeline_arg",
      default_value=10)
    
  2. Tambahkan objek PipelineParameter ini sebagai parameter ke salah satu langkah dalam alur sebagai berikut:

    compareStep = PythonScriptStep(
      script_name="compare.py",
      arguments=["--comp_data1", comp_data1, "--comp_data2", comp_data2, "--output_data", out_data3, "--param1", pipeline_param],
      inputs=[ comp_data1, comp_data2],
      outputs=[out_data3],
      compute_target=compute_target,
      source_directory=project_folder)
    
  3. Publikasikan alur ini, yang akan menerima parameter ketika dipanggil.

    published_pipeline1 = pipeline_run1.publish_pipeline(
         name="My_Published_Pipeline",
         description="My Published Pipeline Description",
         version="1.0")
    
  4. Setelah menerbitkan alur, Anda dapat memeriksanya di antarmuka pengguna. ID Alur adalah id unik yang diidentifikasi dari alur yang diterbitkan.

    Cuplikan layar yang menampilkan detail alur yang diterbitkan.

Mengeksekusi alur yang diterbitkan

Semua alur yang diterbitkan memiliki titik akhir REST. Dengan titik akhir alur, Anda dapat memicu eksekusi alur dari sistem eksternal apa pun, termasuk klien non-Python. Titik akhir ini memungkinkan "pengulangan terkelola" dalam skenario penilaian dan pelatihan ulang batch.

Penting

Jika Anda menggunakan kontrol akses berbasis peran Azure (RBAC Azure) untuk mengelola akses ke alur Anda, atur izin untuk skenario alur Anda (pelatihan atau penilaian).

Untuk memanggil eksekusi alur sebelumnya, Anda memerlukan token header autentikasi Microsoft Entra. Mendapatkan token seperti itu dijelaskan dalam referensi kelas AzureCliAuthentication dan di buku catatan Autentikasi di Azure Machine Learning.

from azureml.pipeline.core import PublishedPipeline
import requests

response = requests.post(published_pipeline1.endpoint,
                         headers=aad_token,
                         json={"ExperimentName": "My_Pipeline",
                               "ParameterAssignments": {"pipeline_arg": 20}})

Argumen json untuk permintaan POST harus berisi, untuk kunci ParameterAssignments, kamus yang berisi parameter alur dan nilainya. Selain itu, argumen json dapat berisi tombol berikut:

Kunci Deskripsi
ExperimentName Nama eksperimen yang terkait dengan titik akhir ini
Description Teks bentuk bebas yang menjelaskan titik akhir
Tags Pasangan kunci-nilai bentuk bebas yang dapat digunakan untuk memberi label dan membuat anotasi permintaan
DataSetDefinitionValueAssignments Kamus yang digunakan untuk mengubah himpunan data tanpa pelatihan ulang (lihat diskusi di bawah)
DataPathAssignments Kamus yang digunakan untuk mengubah datapath tanpa pelatihan ulang (lihat diskusi di bawah)

Mengeksekusi alur yang diterbitkan menggunakan C #

Kode berikut menunjukkan cara memanggil alur secara asinkron dari C#. Cuplikan kode parsial hanya menampilkan struktur panggilan dan bukan bagian dari sampel Microsoft. Cuplikan kode ini tidak menampilkan kelas lengkap atau penanganan kesalahan.

[DataContract]
public class SubmitPipelineRunRequest
{
    [DataMember]
    public string ExperimentName { get; set; }

    [DataMember]
    public string Description { get; set; }

    [DataMember(IsRequired = false)]
    public IDictionary<string, string> ParameterAssignments { get; set; }
}

// ... in its own class and method ... 
const string RestEndpoint = "your-pipeline-endpoint";

using (HttpClient client = new HttpClient())
{
    var submitPipelineRunRequest = new SubmitPipelineRunRequest()
    {
        ExperimentName = "YourExperimentName", 
        Description = "Asynchronous C# REST api call", 
        ParameterAssignments = new Dictionary<string, string>
        {
            {
                // Replace with your pipeline parameter keys and values
                "your-pipeline-parameter", "default-value"
            }
        }
    };

    string auth_key = "your-auth-key"; 
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", auth_key);

    // submit the job
    var requestPayload = JsonConvert.SerializeObject(submitPipelineRunRequest);
    var httpContent = new StringContent(requestPayload, Encoding.UTF8, "application/json");
    var submitResponse = await client.PostAsync(RestEndpoint, httpContent).ConfigureAwait(false);
    if (!submitResponse.IsSuccessStatusCode)
    {
        await WriteFailedResponse(submitResponse); // ... method not shown ...
        return;
    }

    var result = await submitResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
    var obj = JObject.Parse(result);
    // ... use `obj` dictionary to access results
}

Mengeksekusi alur yang diterbitkan menggunakan Java

Kode berikut ini memperlihatkan panggilan ke alur yang memerlukan autentikasi (lihat Menyiapkan autentikasi untuk sumber daya dan alur kerja Azure Machine Learning). Jika alur Anda disebarkan secara publik, Anda tidak memerlukan panggilan yang menghasilkan authKey. Cuplikan kode parsial tidak menampilkan kelas Java dan boilerplate penanganan pengecualian. Kode ini menggunakan Optional.flatMap untuk penautan fungsi-fungsi yang dapat mengembalikan Optional kosong. Penggunaan flatMap memperpendek dan mengklarifikasi kode, tetapi perhatikan bahwa getRequestBody() menelan pengecualian.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Optional;
// JSON library
import com.google.gson.Gson;

String scoringUri = "scoring-endpoint";
String tenantId = "your-tenant-id";
String clientId = "your-client-id";
String clientSecret = "your-client-secret";
String resourceManagerUrl = "https://management.azure.com";
String dataToBeScored = "{ \"ExperimentName\" : \"My_Pipeline\", \"ParameterAssignments\" : { \"pipeline_arg\" : \"20\" }}";

HttpClient client = HttpClient.newBuilder().build();
Gson gson = new Gson();

HttpRequest tokenAuthenticationRequest = tokenAuthenticationRequest(tenantId, clientId, clientSecret, resourceManagerUrl);
Optional<String> authBody = getRequestBody(client, tokenAuthenticationRequest);
Optional<String> authKey = authBody.flatMap(body -> Optional.of(gson.fromJson(body, AuthenticationBody.class).access_token);;
Optional<HttpRequest> scoringRequest = authKey.flatMap(key -> Optional.of(scoringRequest(key, scoringUri, dataToBeScored)));
Optional<String> scoringResult = scoringRequest.flatMap(req -> getRequestBody(client, req));
// ... etc (`scoringResult.orElse()`) ... 

static HttpRequest tokenAuthenticationRequest(String tenantId, String clientId, String clientSecret, String resourceManagerUrl)
{
    String authUrl = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId);
    String clientIdParam = String.format("client_id=%s", clientId);
    String resourceParam = String.format("resource=%s", resourceManagerUrl);
    String clientSecretParam = String.format("client_secret=%s", clientSecret);

    String bodyString = String.format("grant_type=client_credentials&%s&%s&%s", clientIdParam, resourceParam, clientSecretParam);

    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(authUrl))
        .POST(HttpRequest.BodyPublishers.ofString(bodyString))
        .build();
    return request;
}

static HttpRequest scoringRequest(String authKey, String scoringUri, String dataToBeScored)
{
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create(scoringUri))
        .header("Authorization", String.format("Token %s", authKey))
        .POST(HttpRequest.BodyPublishers.ofString(dataToBeScored))
        .build();
    return request;

}

static Optional<String> getRequestBody(HttpClient client, HttpRequest request) {
    try {
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() != 200) {
            System.out.println(String.format("Unexpected server response %d", response.statusCode()));
            return Optional.empty();
        }
        return Optional.of(response.body());
    }catch(Exception x)
    {
        System.out.println(x.toString());
        return Optional.empty();
    }
}

class AuthenticationBody {
    String access_token;
    String token_type;
    int expires_in;
    String scope;
    String refresh_token;
    String id_token;
    
    AuthenticationBody() {}
}

Mengubah himpunan data dan datapath tanpa pelatihan ulang

Anda mungkin ingin melatih dan membuat inferensi pada himpunan data dan datapath yang berbeda. Misalnya, Anda mungkin ingin berlatih pada himpunan data yang lebih kecil tetapi membuat inferensi pada himpunan data lengkap. Anda beralih himpunan data dengan kunci DataSetDefinitionValueAssignments dalam argumen json permintaan. Anda beralih datapath dengan DataPathAssignments. Teknik untuk keduanya mirip:

  1. Di skrip definisi alur Anda, buat PipelineParameter untuk himpunan data. Buat DatasetConsumptionConfig atau DataPath dari PipelineParameter:

    tabular_dataset = Dataset.Tabular.from_delimited_files('https://dprepdata.blob.core.windows.net/demo/Titanic.csv')
    tabular_pipeline_param = PipelineParameter(name="tabular_ds_param", default_value=tabular_dataset)
    tabular_ds_consumption = DatasetConsumptionConfig("tabular_dataset", tabular_pipeline_param)
    
  2. Di skrip ML Anda, akses himpunan data yang ditentukan secara dinamis menggunakan Run.get_context().input_datasets:

    from azureml.core import Run
    
    input_tabular_ds = Run.get_context().input_datasets['tabular_dataset']
    dataframe = input_tabular_ds.to_pandas_dataframe()
    # ... etc ...
    

    Perhatikan bahwa skrip ML mengakses nilai yang ditentukan untuk DatasetConsumptionConfig (tabular_dataset) dan bukan nilai PipelineParameter (tabular_ds_param).

  3. Dalam skrip definisi alur Anda, atur DatasetConsumptionConfig sebagai parameter ke PipelineScriptStep:

    train_step = PythonScriptStep(
        name="train_step",
        script_name="train_with_dataset.py",
        arguments=["--param1", tabular_ds_consumption],
        inputs=[tabular_ds_consumption],
        compute_target=compute_target,
        source_directory=source_directory)
    
    pipeline = Pipeline(workspace=ws, steps=[train_step])
    
  4. Untuk beralih himpunan data secara dinamis dalam panggilan REST inferensi, gunakan DataSetDefinitionValueAssignments:

    tabular_ds1 = Dataset.Tabular.from_delimited_files('path_to_training_dataset')
    tabular_ds2 = Dataset.Tabular.from_delimited_files('path_to_inference_dataset')
    ds1_id = tabular_ds1.id
    d22_id = tabular_ds2.id
    
    response = requests.post(rest_endpoint, 
                             headers=aad_token, 
                             json={
                                "ExperimentName": "MyRestPipeline",
                               "DataSetDefinitionValueAssignments": {
                                    "tabular_ds_param": {
                                        "SavedDataSetReference": {"Id": ds1_id #or ds2_id
                                    }}}})
    

Buku catatan yang Menampilkan Himpunan Data dan PipelineParameter serta Menampilkan DataPath dan PipelineParameter memiliki contoh lengkap untuk teknik ini.

Membuat titik akhir alur dengan versi

Anda dapat membuat Titik Akhir Alur dengan beberapa alur yang diterbitkan di baliknya. Teknik ini memberi Anda titik akhir REST tetap saat Anda melakukan perulangan dan memperbarui alur ML Anda.

from azureml.pipeline.core import PipelineEndpoint

published_pipeline = PublishedPipeline.get(workspace=ws, id="My_Published_Pipeline_id")
pipeline_endpoint = PipelineEndpoint.publish(workspace=ws, name="PipelineEndpointTest",
                                            pipeline=published_pipeline, description="Test description Notebook")

Mengirimkan pekerjaan ke titik akhir alur

Anda dapat mengirimkan pekerjaan ke versi default titik akhir alur:

pipeline_endpoint_by_name = PipelineEndpoint.get(workspace=ws, name="PipelineEndpointTest")
run_id = pipeline_endpoint_by_name.submit("PipelineEndpointExperiment")
print(run_id)

Anda juga dapat mengirimkan pekerjaan ke versi tertentu:

run_id = pipeline_endpoint_by_name.submit("PipelineEndpointExperiment", pipeline_version="0")
print(run_id)

Hal yang sama dapat dicapai menggunakan REST API:

rest_endpoint = pipeline_endpoint_by_name.endpoint
response = requests.post(rest_endpoint, 
                         headers=aad_token, 
                         json={"ExperimentName": "PipelineEndpointExperiment",
                               "RunSource": "API",
                               "ParameterAssignments": {"1": "united", "2":"city"}})

Menggunakan alur yang diterbitkan di studio

Anda juga dapat mengeksekusi alur yang diterbitkan dari studio:

  1. Masuk ke Studio Azure Machine Learning.

  2. Lihat ruang kerja Anda.

  3. Di sebelah kiri, pilih Titik akhir.

  4. Di bagian atas, pilih Titik akhir alur. daftar alur yang diterbitkan pembelajaran mesin

  5. Pilih alur tertentu untuk mengeksekusi, mengonsumsi, atau meninjau hasil proses eksekusi sebelumnya dari titik akhir alur.

Menonaktifkan alur yang diterbitkan

Untuk menyembunyikan alur dari daftar alur yang diterbitkan, Anda menonaktifkannya, baik di studio atau dari SDK:

# Get the pipeline by using its ID from Azure Machine Learning studio
p = PublishedPipeline.get(ws, id="068f4885-7088-424b-8ce2-eeb9ba5381a6")
p.disable()

Anda dapat mengaktifkannya lagi dengan p.enable(). Untuk informasi selengkapnya, lihat Referensi kelas PublishedPipeline.

Langkah berikutnya