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. Các ứ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 các nội dung tuỳ chỉnh chính xác được thực hiện cho người dùng (trừ phi có cá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 phần giải thích về tính năng Cá nhân hoá trên thiết bị.
ODP chạy mã của 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 duy trì cục bộ sau đây:
RemoteData– Dữ liệu khoá-giá trị không thay đổi được tải xuống từ các máy chủ 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 được nhà phát triển lưu giữ 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 liên tục: Bạn có thể dùng những đầu ra này trong quá trình xử lý cục bộ sau này, tạo ra đầu ra hiển thị, 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ị.
- Kết quả đầu ra hiển thị:
- Nhà phát triển có thể trả về HTML do ODP kết xuất trong
WebViewbên trongSurfaceView. Ứng dụng gọi sẽ không thấy nội dung được kết xuất ở đó. - Nhà phát triển có thể nhúng URL sự kiện do ODP cung cấp vào đầu ra HTML để kích hoạt quá trình ghi nhật ký và xử lý các lượt 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.
- Nhà phát triển có thể trả về HTML do ODP kết xuất trong
Các ứng dụng và SDK có thể gọi ODP để hiển thị nội dung HTML trong SurfaceView bằng cách sử dụ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 hoặc SDK khách 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 của ứng 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ý hậu kỳ dữ liệu đã tải xuống. Nó cũng dàn xếp mọi hoạt động giao tiếp giữa IsolatedProcess và các dịch vụ cũng như ứng dụng khác.
Cá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 đang chạy trong một IsolatedProcess. Mã của nhà phát triển chạy trong một IsolatedProcess sẽ 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 OnDevicePersonalizationManager và IsolatedWorker.
OnDevicePersonalizationManager và IsolatedWorker.Ứ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 được duy trì và nội dung cần được hiển thị. Dịch vụ ODP ghi đầu ra liên tục vào bảng REQUESTS hoặc EVENTS, đồng thời trả về một tham chiếu không rõ ràng đến đầu ra được hiển thị cho ứng dụng khách. Ứng dụng khách có thể dùng tham chiếu không rõ ràng 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 liên tục
Dịch vụ ODP duy trì một bản ghi trong bảng REQUESTS sau khi quá trình triển khai onExecute của nhà phát triển trả về. Mỗi bản ghi trong bảng REQUESTS chứa một số dữ liệu chung cho mỗi yêu cầu do dịch vụ ODP tạo 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 và có thể báo cáo dữ liệu chuỗi hoặc blob sau khi áp dụng Quyền riêng tư vi phân 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 sẽ ghi lại dấu thời gian và tên gói của ứng dụng gọi cũng như 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:
- Thẻ
<property>trongAndroidManifest.xmltrỏ đến một tài nguyên XML trong gói chứa thông tin cấu hình ODP. - Thẻ
<service>trongAndroidManifest.xmlxác định lớp mở rộngIsolatedService, như minh hoạ trong ví dụ sau. Dịch vụ trong thẻ<service>phải có các thuộc tínhexportedvàisolatedProcessđược đặt thànhtrue. - Thẻ
<service>trong tài nguyên XML được chỉ định ở Bước 1, xác định lớp dịch vụ ở 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 tính toán liên kết, bạn cũng cần chỉ định điểm cuối URL của máy chủ tính toán liên kết mà Máy khách tính 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 công tắc và cờ
ODP có một bộ công tắc và cờ dùng để kiểm soát một số chức năng nhất định:
- _global_killswitch: công tắc 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ả cá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 đối tượng được phép gọi ODP, bạn có thể thêm các ứng dụng (tên gói, [không bắt buộc] chứng chỉ) vào đây hoặc đặt là * để cho phép tất cả
- _isolated_service_allowlist: kiểm soát những dịch vụ có thể chạy trong quy trình Dịch vụ biệt lập.
Bạn có thể chạy các lệnh sau để thiết lập tất cả các công tắc 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.
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 có ý đị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 khi chạy trong một quy trình riêng biệt. Dịch vụ ODP sẽ bắt đầu 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 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, quá trình tải xuống hoàn tất và các sự kiện do HTML được 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 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 những 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 đang 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ể dùng đối tượng SurfacePackageToken được trả về trong một lệnh gọi requestSurfacePackage tiếp theo để yêu cầu kết quả được kết xuất trong một SurfaceView .
Khi thành công, phương thức nhận sẽ được gọi bằng một SurfacePackage cho một Chế độ xem do dịch vụ ODP kết xuất. 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ị của chúng.
Khi một ứng dụng thực hiện lệnh gọi requestSurfacePackage bằng SurfacePackageToken do lệnh gọi OnDevicePersonalizationManager#execute trước đó trả về, dịch vụ ODP sẽ gọi IsolatedWorker#onRender để tìm nạp đoạn mã HTML sẽ được kết xuất trong một khung được phân vùng. 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ó khả năng nhạy cảm trong URL tìm nạp tài sản trong HTML đã tạo. Nhà phát triển có thể sử dụng IsolatedService#getEventUrlProvider để tạo URL theo dõi nhằm đưa vào HTML đã tạo. Khi HTML được 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 đượ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 được hiển thị, gọi IsolatedWorker#onEvent và ghi EventLogRecord được trả về vào bảng EVENTS.
Viết kết quả liên tục
Với OnDevicePersonalizationManager#execute, dịch vụ này có thể ghi dữ liệu vào bộ nhớ liên tục (các bảng REQUESTS và EVENTS). Sau đây là những mục mà người dùng có thể viết vào các bảng này:
RequestLogRecordsẽ được thêm vào bảngREQUESTS.- một danh sách các đối tượng
EventLogRecordsẽ được thêm vào bảngEVENTS, mỗi đối tượng chứa một con trỏ đếnRequestLogRecordđã được ghi trước đó .
Kết quả liên tục trong bộ nhớ trên thiết bị có thể được Học liên kết sử dụng để 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 lệnh tính toán liên kết bắt đầu và muốn nhận các ví dụ huấn luyện do những nhà phát triển sử dụng ODP cung cấp. Bạn có thể gọi getRemoteData(), getLocalData(), getUserData() và getLogReader() khi triển khai onTrainingExample().
Để lên lịch hoặc huỷ các lệnh 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ả ODP IsolatedService. Bạn có thể xác định từng lệnh tính toán liên kết bằng tên của nhóm.
Trước khi lên lịch cho một lệnh tính toán liên kết mới:
- Một tác vụ có tên 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.
- Điểm cuối URL của máy chủ tính toán liên kết phải được chỉ định 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 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 các bảng cục bộ
Lớp LogReader cung cấp các API để đọc bảng REQUESTS và EVENTS. 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ị.
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. Nội dung tải xuống là một 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ào của nội dung đã tải xuống vào bảng RemoteData và tập hợp con nào sẽ bị 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ể tự do điền vào bảng LocalData theo ý muốn; ví dụ: họ có thể lưu vào bộ nhớ đệm một số kết quả được tính toán trước.
Đị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 của 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 này 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 một 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 được điền sẵn. Giá trị syncToken phải là dấu thời gian tính bằng giây, được giới hạn trong 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 gia tăng.
Định dạng tệp tải xuống
Tệp được tải xuống là một 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 giới hạn trong một ranh giới giờ và phải vượt quá syncToken của lần 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à một danh sách các bộ (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ột 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 lệnh tính toán liên kết ở phía máy khách, bạn cần một tác vụ có tên nhóm đượ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.
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 2 nhóm tệp:
- Một 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.
- Một 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ư vi sai. 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 nhiều mẫu khác trong kho lưu trữ GitHub của chúng tôi.
Sau khi chuẩn bị hai đầ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 các 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.