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 chi tiết, 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 một 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 mà 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ợ:

  • Kết quả ổn định: Những dữ liệu đầu ra này có thể được dùng trong quá trình xử lý cục bộ trong tương lai, tạo ra các kết quả hiển thị, 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 hỗ trợ việc phân tích số liệu thống kê trên nhiều thiết bị.
    • Nhà phát triển có thể ghi 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 kết xuất trong WebView bên trong SurfaceView. Nội dung được kết xuất ở đó sẽ không hiển thị với ứng dụng đang gọi.
    • 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 việc ghi nhật ký và xử lý các hoạt động tương tác của người dùng với HTML được 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. Nội dung được hiển thị trong SurfaceView không hiển thị với ứng dụng gọi. Ứ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. Phương thức 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ý hậu kỳ dữ liệu đã tải xuống. Dịch vụ này cũng dàn xếp mọi hoạt động liên lạc giữa IsolatedProcess với 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 sẽ mở rộng lớp IsolatedService và triển khai giao diện IsolatedWorker. IsolatedService cần tạo một bản sao của IsolatedWorker cho từng 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ơ đồ mối quan hệ giữa OnDevicePersonalizationManagerIsolatedWorker.

Một ứng dụng khách gọi ODP bằng phương thức execute với IsolatedService được đặt tên. 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 cố định vào bảng REQUESTS hoặc EVENTS và trả về một 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 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 của ứng dụng.

Đầu ra ổn định

Dịch vụ ODP duy 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. Các giá trị số có thể được báo cáo sau khi tổng hợp, và có thể báo cáo dữ liệu chuỗi hoặc blob sau khi áp dụng Sự riêng tư biệt lập cục bộ hoặc trung tâm. 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 phải đáp ứng các yêu cầu sau:

  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 thẻ, như minh hoạ 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 chuyển đổi và gắn cờ

ODP có một bộ công tắc và cờ dùng để điều khiển một số chức năng:

  • _global_killswitch: nút chuyển chung cho tất cả cá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]) vào đâ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 về API Android cho ODP.

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 riêng biệt và đưa ra yêu cầu đối với dịch vụ đó. IsolatedService nhận yêu cầu từ dịch vụ ODP và tạo một 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, các lượt hoàn thành việc tải xuống, cũng như 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ó phương thức triển khai mặc định không hoạt động, 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 cho 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 cần hiển thị, với OnDevicePersonalizationManager#execute, ứng dụng gọi có thể 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ả 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 requestSurfacePackageSurfacePackageToken do OnDevicePersonalizationManager#execute trước đó trả về, sẽ gọi dịch vụ ODP IsolatedWorker#onRender để tìm nạp đoạn mã HTML cần hiển thị trong khung 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 ngăn nhà phát triển nhúng UserData có khả năng nhạy cảm trong các URL tìm nạp thành phần vào HTML đã 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. Người dùng 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 dữ liệu đầu ra HTML. Khi HTML được 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ể ghi vào bảng này:

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

Tính năng 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ý nhiệm vụ đào tạo 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ề 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.

Số lượt tương tác với kết quả liên tục

Phần sau đây mô tả cách tương tác với đầu ra liên tục 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(). Bạn có thể dùng dữ liệu trong các bảng này để 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ị.

Các nhà phát triển dùng ODP có thể chọn những nhóm nội dung được tải xuống sẽ được thêm vào bảng RemoteData và những nội dung nào sẽ được loại bỏ. 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ể thoải mái điền sẵn vào bảng LocalData theo lựa chọn của họ; ví dụ: họ có thể lưu một số kết quả đã tính trước vào bộ nhớ đệm.

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

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

Điểm cuối dự kiến sẽ trả về phản hồi JSON như mô tả ở phần sau. Phản hồi JSON phải chứa syncToken xác định phiên bản của dữ liệu đang được gửi, cùng với danh sách các cặp khoá-giá trị cần điền. Giá trị syncToken phải là dấu thời gian tính bằng giây, được gắn với 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 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ừng tệp tải xuống dần.

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

Tệp được tải xuống là tệp JSON có cấu trúc như 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 được dự kiến 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. Trường này có thể được đặt thành "utf8" hoặc "base64" và được giả định là "utf8" theo mặc định. 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 tôi sẽ đề cập đến cách tạo một tác vụ như vậy trên máy chủ điện toán liên kết.

Sơ đồ về cấu trúc máy chủ-ứng dụng điện 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 các mẫu khác trong kho lưu trữ GitHub của chúng tôi.

Sau khi chuẩn bị 2 thông tin đầu vào này, hãy gọi Task Builder để tạo cấu phần phần mềm và tạo nhiệm 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.