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ị.
- 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 trongSurfaceView
. 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
.
- Nhà phát triển có thể trả về HTML do ODP kết xuất trong
Ứ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 OnDevicePersonalizationManager
và IsolatedWorker
.
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:
- Thẻ
<property>
trongAndroidManifest.xml
trỏ đến một tài nguyên XML trong gói chứa thông tin cấu hình ODP. - Thẻ
<service>
trongAndroidManifest.xml
xác định lớp mở rộngIsolatedService
, như trong ví dụ sau. Dịch vụ trong thẻ<service>
phải có các thuộc tínhexported
và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ụ 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 requestSurfacePackage
có SurfacePackageToken
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 REQUESTS
và EVENTS
). 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ảngREQUESTS
.- danh sách đối tượng
EventLogRecord
cần thêm vào bảngEVENTS
, mỗi đối tượng chứa một con trỏ đếnRequestLogRecord
đã 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()
và 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 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ị.
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.
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:
- 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.
- 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.