Hướng dẫn cho nhà phát triển hoạt động Cá nhân hoá trên thiết bị

Tính năng Cá nhân hoá trên thiết bị (ODP) được thiết kế để bảo vệ thông tin của người dùng cuối khỏi các ứng dụng. Ứng dụng sử dụng ODP để tuỳ chỉnh sản phẩm và dịch vụ cho người dùng cuối, nhưng sẽ không thể xem chính xác nội dung tuỳ chỉnh được thực hiện cho người dùng (trừ phi có hoạt động tương tác trực tiếp bên ngoài ODP giữa ứng dụng và người dùng cuối). Đối với các ứng dụng có mô hình học máy hoặc phân tích thống kê, ODP cung cấp một bộ dịch vụ và thuật toán để đảm bảo rằng các ứng dụng đó được ẩn danh đúng cách bằng cách sử dụng các cơ chế thích hợp về Sự riêng tư biệt lập. Để biết thêm thông tin, hãy xem nội dung giải thích về Cá nhân hoá trên thiết bị.

ODP chạy mã nhà phát triển trong IsolatedProcess không có quyền truy cập trực tiếp vào mạng, ổ đĩa cục bộ hoặc các dịch vụ khác đang chạy trên thiết bị, nhưng có quyền truy cập vào các nguồn dữ liệu được lưu trữ cục bộ sau đây:

  • RemoteData – Dữ liệu khoá-giá trị không thể thay đổi được tải xuống từ các phần phụ trợ từ xa do nhà phát triển vận hành, nếu có.
  • LocalData – Dữ liệu khoá-giá trị có thể thay đổi do nhà phát triển lưu trữ cục bộ (nếu có).
  • UserData – Dữ liệu người dùng do nền tảng cung cấp.

Các đầu ra sau đây được hỗ trợ:

  • Đầu ra ổn định: Bạn có thể sử dụng các đầu ra này trong quá trình xử lý cục bộ trong tương lai, tạo đầu ra hiển thị, huấn luyện mô hình được hỗ trợ bởi tính năng Học liên kết hoặc phân tích số liệu thống kê trên nhiều thiết bị được hỗ trợ bởi Phân tích liên kết.
    • Nhà phát triển có thể ghi các yêu cầu cũng như kết quả xử lý vào bảng REQUESTS cục bộ.
    • Nhà phát triển có thể ghi dữ liệu bổ sung liên kết với một yêu cầu trước đó vào bảng EVENTS.
  • Kết quả hiển thị:
    • Nhà phát triển có thể trả về HTML do ODP hiển thị trong WebView bên trong SurfaceView. Ứng dụng gọi sẽ không thấy được nội dung hiển thị ở đó.
    • Nhà phát triển có thể nhúng URL sự kiện do ODP cung cấp trong đầu ra HTML để kích hoạt tính năng ghi nhật ký và xử lý các lượt tương tác của người dùng với HTML đã hiển thị. ODP chặn các yêu cầu đến những URL đó và gọi mã để tạo dữ liệu được ghi vào bảng EVENTS.

Ứng dụng khách và SDK có thể gọi ODP để hiển thị nội dung HTML trong SurfaceView bằng các API ODP. Ứng dụng gọi không thấy nội dung được kết xuất trong SurfaceView. Ứng dụng khách hoặc SDK có thể là một thực thể khác với thực thể đang phát triển bằng ODP.

Dịch vụ ODP quản lý ứng dụng khách muốn gọi ODP để hiển thị nội dung được cá nhân hoá trong giao diện người dùng. Thư viện này tải nội dung xuống từ các điểm cuối do nhà phát triển cung cấp và gọi logic để xử lý sau dữ liệu đã tải xuống. Ứng dụng này cũng dàn xếp tất cả hoạt động giao tiếp giữa IsolatedProcess và các dịch vụ và ứng dụng khác.

Ứng dụng khách sử dụng các phương thức trong lớp OnDevicePersonalizationManager để tương tác với mã của nhà phát triển chạy trong IsolatedProcess. Mã của nhà phát triển chạy trong IsolatedProcess mở rộng lớp IsolatedService và triển khai giao diện IsolatedWorker. IsolatedService cần tạo một thực thể của IsolatedWorker cho mỗi yêu cầu.

Sơ đồ sau đây cho thấy mối quan hệ giữa các phương thức trong OnDevicePersonalizationManagerIsolatedWorker.

Sơ đồ về mối quan hệ giữa OnDevicePersonalizationManagerIsolatedWorker.

Ứng dụng khách gọi ODP bằng phương thức execute có tên là IsolatedService. Dịch vụ ODP chuyển tiếp lệnh gọi đến phương thức onExecute của IsolatedWorker. IsolatedWorker trả về các bản ghi cần duy trì và nội dung cần hiển thị. Dịch vụ ODP ghi đầu ra ổn định vào bảng REQUESTS hoặc EVENTS và trả về một tệp tham chiếu mờ đến đầu ra hiển thị cho ứng dụng khách. Ứng dụng khách có thể sử dụng tệp tham chiếu mờ này trong lệnh gọi requestSurfacePackage trong tương lai để hiển thị bất kỳ nội dung hiển thị nào trong giao diện người dùng.

Đầu ra ổn định

Dịch vụ ODP sẽ lưu trữ một bản ghi trong bảng REQUESTS sau khi nhà phát triển triển khai onExecute trả về. Mỗi bản ghi trong bảng REQUESTS chứa một số dữ liệu phổ biến cho mỗi yêu cầu do dịch vụ ODP tạo ra và danh sách Rows được trả về. Mỗi Row chứa một danh sách các cặp (key, value). Mỗi giá trị là một đại lượng vô hướng, Chuỗi hoặc blob. Bạn có thể báo cáo các giá trị số sau khi tổng hợp, cũng như báo cáo dữ liệu chuỗi hoặc blob sau khi áp dụng tính năng Sự riêng tư vi phân cục bộ hoặc tập trung. Nhà phát triển cũng có thể ghi các sự kiện tương tác tiếp theo của người dùng vào bảng EVENTS – mỗi bản ghi trong bảng EVENTS được liên kết với một hàng trong bảng REQUESTS. Dịch vụ ODP ghi lại một dấu thời gian và tên gói của ứng dụng gọi cùng với tệp APK của nhà phát triển ODP một cách minh bạch với mỗi bản ghi.

Trước khi bắt đầu

Trước khi bắt đầu phát triển bằng ODP, bạn cần thiết lập tệp kê khai gói và bật chế độ nhà phát triển.

Cài đặt tệp kê khai gói

Để sử dụng ODP, bạn cần có:

  1. Thẻ <property> trong AndroidManifest.xml trỏ đến một tài nguyên XML trong gói chứa thông tin cấu hình ODP.
  2. Thẻ <service> trong AndroidManifest.xml xác định lớp mở rộng IsolatedService, như trong ví dụ sau. Dịch vụ trong thẻ <service> phải có các thuộc tính exportedisolatedProcess được đặt thành true.
  3. Thẻ <service> trong tài nguyên XML được chỉ định ở Bước 1 xác định lớp dịch vụ từ Bước 2. Thẻ <service> cũng phải bao gồm các chế độ cài đặt bổ sung dành riêng cho ODP bên trong chính thẻ đó, như trong ví dụ thứ hai.

AndroidManifest.xml

<!-- Contents of AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.odpsample" >
    <application android:label="OdpSample">
        <!-- XML resource that contains other ODP settings. -->
        <property android:name="android.ondevicepersonalization.ON_DEVICE_PERSONALIZATION_CONFIG"
                  android:resource="@xml/OdpSettings"></property>
        <!-- The service that ODP binds to. -->
        <service android:name="com.example.odpsample.SampleService"
                android:exported="true" android:isolatedProcess="true" />
    </application>
</manifest>

Tệp kê khai dành riêng cho ODP trong tài nguyên XML

Tệp tài nguyên XML được chỉ định trong thẻ <property> cũng phải khai báo lớp dịch vụ trong thẻ <service> và chỉ định điểm cuối URL mà ODP sẽ tải nội dung xuống để điền vào bảng RemoteData, như trong ví dụ sau. Nếu đang sử dụng các tính năng điện toán liên kết, bạn cũng cần chỉ định điểm cuối URL của máy chủ điện toán liên kết mà Ứng dụng điện toán liên kết sẽ kết nối.

<!-- Contents of res/xml/OdpSettings.xml -->
<on-device-personalization>
   <!-- Name of the service subclass -->
   <service name="com.example.odpsample.SampleService">
     <!-- If this tag is present, ODP will periodically poll this URL and
          download content to populate REMOTE_DATA. Developers that do not need to
          download content from their servers can skip this tag. -->
     <download-settings url="https://example.com/get" />
     <!-- If you want to use federated compute feature to train a model, you
          need to specify this tag. -->
     <federated-compute-settings url="https://fcpserver.example.com/" />
   </service>
</on-device-personalization>

Bật Chế độ nhà phát triển

Bật chế độ nhà phát triển bằng cách làm theo hướng dẫn trong phần Bật tuỳ chọn cho nhà phát triển của tài liệu Android Studio.

Cài đặt nút chuyển và cờ

ODP có một bộ nút chuyển và cờ dùng để kiểm soát một số chức năng nhất định:

  • _global_killswitch: nút chuyển chung cho tất cả tính năng ODP; đặt thành false để sử dụng ODP
  • _federated_compute_kill_switch: _công tắc kiểm soát tất cả chức năng huấn luyện (học liên kết) của ODP; đặt thành false để sử dụng tính năng huấn luyện
  • _caller_app_allowlist: kiểm soát những người được phép gọi ODP, bạn có thể thêm ứng dụng (tên gói, chứng chỉ [không bắt buộc]) tại đây hoặc đặt thành * để cho phép tất cả
  • _isolated_service_allowlist: kiểm soát những dịch vụ nào có thể chạy trong quy trình Dịch vụ tách biệt.

Bạn có thể chạy các lệnh sau để định cấu hình tất cả các nút chuyển và cờ để sử dụng ODP mà không bị hạn chế:

# Set flags and killswitches
adb shell device_config set_sync_disabled_for_tests persistent
adb shell device_config put on_device_personalization global_kill_switch false
adb shell device_config put on_device_personalization federated_compute_kill_switch false
adb shell device_config put on_device_personalization caller_app_allow_list \"*\"
adb shell device_config put on_device_personalization isolated_service_allow_list \"*\"

API phía thiết bị

Hãy xem tài liệu tham khảo API Android về ODP.

Các hoạt động tương tác với IsolatedService

Lớp IsolatedService là một lớp cơ sở trừu tượng mà tất cả nhà phát triển dự định phát triển dựa trên ODP đều phải mở rộng và khai báo trong tệp kê khai gói là chạy trong một quy trình riêng biệt. Dịch vụ ODP khởi động dịch vụ này trong một quy trình tách biệt và gửi yêu cầu đến dịch vụ đó. IsolatedService nhận yêu cầu từ dịch vụ ODP và tạo IsolatedWorker để xử lý yêu cầu.

Nhà phát triển cần triển khai các phương thức từ giao diện IsolatedWorker để xử lý các yêu cầu của ứng dụng khách, lượt tải xuống hoàn tất và các sự kiện do HTML đã kết xuất kích hoạt. Tất cả các phương thức này đều có cách triển khai không hoạt động theo mặc định, vì vậy, nhà phát triển có thể bỏ qua việc triển khai các phương thức mà họ không quan tâm.

Lớp OnDevicePersonalizationManager cung cấp một API để các ứng dụng và SDK tương tác với IsolatedService do nhà phát triển triển khai chạy trong một quy trình tách biệt. Sau đây là một số trường hợp sử dụng dự kiến:

Tạo nội dung HTML để hiển thị trong SurfaceView

Để tạo nội dung hiển thị, với OnDevicePersonalizationManager#execute, ứng dụng gọi có thể sử dụng đối tượng SurfacePackageToken được trả về trong lệnh gọi requestSurfacePackage tiếp theo để yêu cầu kết quả được hiển thị trong SurfaceView .

Khi thành công, trình nhận sẽ được gọi bằng SurfacePackage cho một Chế độ xem do dịch vụ ODP hiển thị. Các ứng dụng khách cần chèn SurfacePackage vào SurfaceView trong hệ phân cấp Khung hiển thị.

Khi một ứng dụng thực hiện lệnh gọi requestSurfacePackage với SurfacePackageToken do lệnh gọi OnDevicePersonalizationManager#execute trước đó trả về, hãy gọi lệnh gọi dịch vụ ODP IsolatedWorker#onRender để tìm nạp đoạn mã HTML sẽ hiển thị trong một khung được bảo vệ. Nhà phát triển không có quyền truy cập vào LocalData hoặc UserData trong giai đoạn này. Điều này giúp nhà phát triển không nhúng UserData có thể nhạy cảm trong URL tìm nạp tài sản trong HTML được tạo. Nhà phát triển có thể sử dụng IsolatedService#getEventUrlProvider để tạo URL theo dõi để đưa vào HTML đã tạo. Khi HTML hiển thị, dịch vụ ODP sẽ chặn các yêu cầu đến những URL này và gọi IsolatedWorker#onEvent. Bạn có thể gọi getRemoteData() khi triển khai onRender().

Theo dõi sự kiện trong nội dung HTML

Lớp EventUrlProvider cung cấp các API để tạo URL theo dõi sự kiện mà nhà phát triển có thể đưa vào đầu ra HTML. Khi HTML hiển thị, ODP sẽ gọi IsolatedWorker#onEvent bằng tải trọng của URL sự kiện.

Dịch vụ ODP chặn các yêu cầu đến URL sự kiện do ODP tạo trong HTML đã hiển thị, gọi IsolatedWorker#onEvent và ghi EventLogRecord được trả về vào bảng EVENTS.

Ghi kết quả ổn định

Với OnDevicePersonalizationManager#execute, dịch vụ có thể ghi dữ liệu vào bộ nhớ cố định (bảng REQUESTSEVENTS). Sau đây là các mục nhập mà người dùng có thể viết vào các bảng này:

  • RequestLogRecord sẽ được thêm vào bảng REQUESTS.
  • danh sách các đối tượng EventLogRecord sẽ được thêm vào bảng EVENTS, mỗi đối tượng chứa một con trỏ đến RequestLogRecord đã ghi trước đó .

Học liên kết có thể sử dụng kết quả ổn định trong bộ nhớ trên thiết bị để huấn luyện mô hình.

Quản lý các tác vụ huấn luyện trên thiết bị

Dịch vụ ODP gọi IsolatedWorker#onTrainingExample khi một công việc huấn luyện điện toán liên kết bắt đầu và muốn nhận các ví dụ về việc huấn luyện do các nhà phát triển sử dụng ODP cung cấp. Bạn có thể gọi getRemoteData(), getLocalData(), getUserData()getLogReader() khi triển khai onTrainingExample().

Để lên lịch hoặc huỷ các công việc tính toán liên kết, bạn có thể sử dụng lớp FederatedComputeScheduler. Lớp này cung cấp API cho tất cả IsolatedService ODP. Bạn có thể xác định từng công việc tính toán liên kết bằng tên của quần thể.

Trước khi bạn lên lịch cho một công việc tính toán liên kết mới:

  • Một tác vụ có tên của tập hợp này phải được tạo trên máy chủ tính toán liên kết từ xa.
  • Bạn phải chỉ định điểm cuối URL của máy chủ tính toán liên kết trong chế độ cài đặt tệp kê khai gói bằng thẻ federated-compute-settings.

Tương tác với đầu ra ổn định

Phần sau đây mô tả cách tương tác với đầu ra ổn định trong ODP.

Đọc bảng cục bộ

Lớp LogReader cung cấp các API để đọc bảng REQUESTSEVENTS. Các bảng này chứa dữ liệu do IsolatedService ghi trong các lệnh gọi onExecute() hoặc onEvent(). Dữ liệu trong các bảng này có thể được dùng trong quy trình huấn luyện mô hình hỗ trợ tính năng Học liên kết hoặc Phân tích liên kết để phân tích số liệu thống kê trên nhiều thiết bị.

Hoạt động tương tác với nội dung đã tải xuống

Phần sau đây mô tả cách tương tác với nội dung đã tải xuống trong ODP.

Tải nội dung xuống từ máy chủ

Dịch vụ ODP định kỳ tải nội dung xuống từ URL được khai báo trong tệp kê khai gói của IsolatedService và gọi onDownloadCompleted sau khi quá trình tải xuống hoàn tất. Tệp tải xuống là tệp JSON chứa các cặp khoá-giá trị.

Nhà phát triển sử dụng ODP có thể chọn thêm tập hợp con nội dung đã tải xuống vào bảng RemoteData và loại bỏ tập hợp con nào. Nhà phát triển không thể sửa đổi nội dung đã tải xuống – điều này đảm bảo rằng bảng RemoteData không chứa bất kỳ dữ liệu người dùng nào. Ngoài ra, nhà phát triển có thể tự do điền bảng LocalData theo ý muốn; ví dụ: họ có thể lưu một số kết quả được tính toán trước vào bộ nhớ đệm.

Định dạng yêu cầu tải xuống

ODP định kỳ thăm dò ý kiến điểm cuối URL được khai báo trong tệp kê khai gói của nhà phát triển để tìm nạp nội dung nhằm điền sẵn bảng RemoteData.

Điểm cuối dự kiến sẽ trả về một phản hồi JSON như mô tả sau. Phản hồi JSON phải chứa syncToken xác định phiên bản dữ liệu đang được gửi, cùng với danh sách các cặp khoá-giá trị cần được điền sẵn. Giá trị syncToken phải là dấu thời gian tính bằng giây, được cố định ở ranh giới giờ UTC. Trong yêu cầu tải xuống, ODP cung cấp syncToken của tệp tải xuống đã hoàn tất trước đó và quốc gia của thiết bị dưới dạng các tham số syncToken và country trong URL tải xuống. Máy chủ có thể sử dụng syncToken trước đó để triển khai tính năng tải xuống tăng dần.

Định dạng tệp tải xuống

Tệp đã tải xuống là tệp JSON có cấu trúc sau. Tệp JSON dự kiến sẽ chứa một syncToken để xác định phiên bản dữ liệu đang được tải xuống. syncToken phải là dấu thời gian UTC được cố định ở ranh giới một giờ và phải lớn hơn syncToken của lượt tải xuống trước đó. Nếu syncToken không đáp ứng cả hai yêu cầu, nội dung đã tải xuống sẽ bị loại bỏ mà không được xử lý.

Trường nội dung là danh sách các bộ dữ liệu (khoá, dữ liệu, mã hoá). key dự kiến sẽ là một chuỗi UTF-8. Trường encoding là một tham số không bắt buộc chỉ định cách mã hoá trường data – bạn có thể đặt trường này thành "utf8" hoặc "base64" và theo mặc định, trường này được giả định là "utf8". Trường key được chuyển đổi thành đối tượng String và trường data được chuyển đổi thành mảng byte trước khi gọi onDownloadCompleted().

{
  // syncToken must be a UTC timestamp clamped to an hour boundary, and must be
  // greater than the syncToken of the previously completed download.
  "syncToken": <timeStampInSecRoundedToUtcHour>,
  "contents": [
    // List of { key, data } pairs.
    { "key": "key1",
      "data": "data1"
    },
    { "key": "key2",
      "data": "data2",
      "encoding": "base64"
    },
    // ...
  ]
}

API phía máy chủ

Phần này mô tả cách tương tác với các API máy chủ điện toán liên kết.

API máy chủ điện toán liên kết

Để lên lịch cho một công việc tính toán liên kết ở phía máy khách, bạn cần có một tác vụ có tên quần thể được tạo trên máy chủ tính toán liên kết từ xa. Trong phần này, chúng ta sẽ đề cập đến cách tạo một tác vụ như vậy trên máy chủ tính toán liên kết.

Sơ đồ về cấu trúc máy chủ-ứng dụng tính toán liên kết.

Khi tạo một tác vụ mới cho Trình tạo tác vụ, nhà phát triển ODP nên cung cấp hai nhóm tệp:

  1. Mô hình tff.learning.models.FunctionalModel đã lưu thông qua lệnh gọi API tff.learning.models.save_functional_model. Bạn có thể tìm thấy một mẫu trong kho lưu trữ GitHub của chúng tôi.
  2. Tệp fcp_server_config.json bao gồm các chính sách, chế độ thiết lập học liên kết và chế độ thiết lập quyền riêng tư biệt lập. Sau đây là ví dụ về fcp_server_config.json:
{
  # Task execution mode.
  mode: TRAINING_AND_EVAL
  # Identifies the set of client devices that participate.
  population_name: "mnist_cnn_task"
  policies {
    # Policy for sampling on-device examples. It is checked every
    # time a device is attempting to start a new training.
    min_separation_policy {
      # The minimum separation required between two successful
      # consective task executions. If a client successfully contributes
      # to a task at index `x`, the earliest they can contribute again
      # is at index `(x + minimum_separation)`. This is required by
      # DP.
      minimum_separation: 1
    }
    data_availability_policy {
      # The minimum number of examples on a device to be considered
      # eligible for training.
      min_example_count: 1
    }
    # Policy for releasing training results to developers adopting ODP.
    model_release_policy {
      # The maximum number of training rounds.
      num_max_training_rounds: 512
    }
  }

  # Federated learning setups. They are applied inside Task Builder.
  federated_learning {
    # Use federated averaging to build federated learning process.
    # Options you can choose:
      # * FED_AVG: Federated Averaging algorithm
      #            (https://arxiv.org/abs/2003.00295)
      # * FED_SGD: Federated SGD algorithm
      #            (https://arxiv.org/abs/1602.05629)
    type: FED_AVG
    learning_process {
      # Optimizer used at client side training. Options you can choose:
      # * ADAM
      # * SGD
      client_optimizer: SGD
      # Learning rate used at client side training.
      client_learning_rate: 0.02
      # Optimizer used at server side training. Options you can choose:
      # * ADAM
      # * SGD
      server_optimizer: SGD
      # Learning rate used at server side training.
      server_learning_rate: 1.0
      runtime_config {
        # Number of participating devices for each round of training.
      report_goal: 2
      }
      metrics {
        name: "sparse_categorical_accuracy"
      }
    }
    evaluation {
      # A checkpoint selector controls how checkpoints are chosen for
      # evaluation. One evaluation task typically runs per training
      # task, and on each round of execution, the eval task
      # randomly picks one checkpoint from the past 24 hours that has
      # been selected for evaluation by these rules.
      # Every_k_round and every_k_hour are definitions of quantization
      # buckets which each checkpoint is placed in for selection.
      checkpoint_selector: "every_1_round"
      # The percentage of a populate that should delicate to this
      # evaluation task.
      evaluation_traffic: 0.2
      # Number of participating devices for each round of evaluation.
      report_goal: 2
    }
  }

  # Differential Privacy setups. They are enforced inside the Task
  # Builder.
  differential_privacy {
    # * fixed_gaussian: DP-SGD with fixed clipping norm described in
    #                   "Learning Differentially Private Recurrent
    #                   Language Models"
    #                   (https://arxiv.org/abs/1710.06963).
    type: FIXED_GAUSSIAN
    #   The value of the clipping norm.
    clip_norm: 0.1
    # Noise multiplier for the Gaussian noise.
    noise_multiplier: 0.1
  }
}

Bạn có thể tìm thấy các mẫu khác trong kho lưu trữ GitHub của chúng tôi.

Sau khi chuẩn bị hai dữ liệu đầu vào này, hãy gọi Trình tạo tác vụ để tạo cấu phần phần mềm và tạo tác vụ mới. Bạn có thể xem hướng dẫn chi tiết hơn trong kho lưu trữ GitHub của chúng tôi.