裝置端個人化 (ODP) 功能的設計宗旨,是要防止應用程式存取使用者的資訊。應用程式會使用 ODP 為使用者量身打造產品和服務,但無法查看為使用者進行的確切自訂項目 (除非應用程式與使用者在 ODP 之外有直接互動)。對於含有機器學習模型或統計分析的應用程式,ODP 提供一系列服務和演算法,確保這些內容妥善完成去識別化。詳情請參閱「裝置端個人化」說明。
ODP 會在IsolatedProcess中執行開發人員程式碼,該IsolatedProcess無法直接存取網路、本機磁碟或裝置上執行的其他服務,但可存取下列本機保存的資料來源:
RemoteData- 從遠端開發人員操作的後端下載的不可變更鍵/值資料 (如適用)。LocalData- 開發人員在本機保留的可變動鍵/值資料 (如適用)。UserData- 平台提供的使用者資料。
支援的輸出內容如下:
- 持續性輸出內容:這些輸出內容可用於日後的本機處理程序,產生顯示的輸出內容、促進聯合學習模型訓練,或促進聯合分析跨裝置統計分析。
- 顯示的輸出內容:
- 開發人員可以傳回 HTML,由 ODP 在
SurfaceView內的WebView中算繪。呼叫應用程式無法看到該處轉譯的內容。 - 開發人員可以在 HTML 輸出內容中嵌入 ODP 提供的事件網址,觸發記錄及處理使用者與轉譯 HTML 的互動。ODP 會攔截傳送至這些網址的要求,並叫用程式碼來產生資料,然後將資料寫入
EVENTS資料表。
- 開發人員可以傳回 HTML,由 ODP 在
用戶端應用程式和 SDK 可以使用 ODP API,在 SurfaceView 中叫用 ODP 來顯示 HTML 內容。在 SurfaceView 中算繪的內容不會顯示給呼叫應用程式。用戶端應用程式或 SDK 可能與使用 ODP 開發的實體不同。
ODP 服務會管理要叫用 ODP 的用戶端應用程式,以便在 UI 中顯示個人化內容。這個外掛程式會從開發人員提供的端點下載內容,並叫用邏輯來後續處理下載的資料。此外,它也會調解 IsolatedProcess 與其他服務和應用程式之間的所有通訊。
用戶端應用程式會使用 OnDevicePersonalizationManager 類別中的方法,與 IsolatedProcess 中執行的開發人員程式碼互動。在 IsolatedProcess 中執行的開發人員程式碼會擴充 IsolatedService 類別,並實作 IsolatedWorker 介面。IsolatedService 必須為每個要求建立 IsolatedWorker 的例項。
下圖顯示 OnDevicePersonalizationManager 和 IsolatedWorker 中的方法之間的關係。
OnDevicePersonalizationManager 和 IsolatedWorker 之間的關係圖。用戶端應用程式會使用 execute 方法呼叫 ODP,並提供具名的 IsolatedService。ODP 服務會將呼叫轉送至 IsolatedWorker 的 onExecute 方法。IsolatedWorker 會傳回要保留的記錄和要顯示的內容。ODP 服務會將持續性輸出內容寫入 REQUESTS 或 EVENTS 資料表,並將顯示輸出內容的不透明參照傳回給用戶端應用程式。用戶端應用程式可在日後的 requestSurfacePackage 呼叫中使用這個不透明參照,在 UI 中顯示任何顯示內容。
持續輸出
開發人員實作 onExecute 傳回後,ODP 服務會在 REQUESTS 表格中保留記錄。REQUESTS 資料表中的每筆記錄都包含 ODP 服務產生的部分常見要求資料,以及傳回的 Rows 清單。每個 Row 都包含 (key, value) 配對清單。每個值都是純量、字串或 Blob。匯總後即可回報數值,套用本機或中央差異化隱私後,即可回報字串或 Blob 資料。開發人員也可以將後續使用者互動事件寫入 EVENTS 資料表,EVENTS 資料表中的每筆記錄都會與 REQUESTS 資料表中的一列建立關聯。ODP 服務會針對每筆記錄,以透明方式記錄時間戳記、呼叫應用程式的套件名稱,以及 ODP 開發人員的 APK。
事前準備
開始使用 ODP 開發前,請先設定套件資訊清單並啟用開發人員模式。
套件資訊清單設定
如要使用 ODP,請務必符合下列條件:
AndroidManifest.xml中的<property>標記,指向套件中的 XML 資源,其中包含 ODP 設定資訊。AndroidManifest.xml中的<service>標記,用於識別擴充IsolatedService的類別,如下列範例所示。<service>標記中的服務必須將exported和isolatedProcess屬性設為true。- 步驟 1 中指定的 XML 資源中的
<service>標記,可識別步驟 2 中的服務類別。<service>標記本身也必須包含其他 ODP 專屬設定,如第二個範例所示。
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>
XML 資源中的 ODP 專屬資訊清單
<property> 標記中指定的 XML 資源檔案也必須在 <service> 標記中宣告服務類別,並指定 ODP 下載內容以填入 RemoteData 表格的網址端點,如下列範例所示。如果您使用聯合運算功能,也需要指定聯合運算伺服器網址端點,聯合運算用戶端會連線至該端點。
<!-- 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>
啟用開發人員模式
按照 Android Studio 說明文件的「啟用開發人員選項」一節中的操作說明,啟用開發人員模式。
切換和旗標設定
ODP 具有一組用於控制特定功能的切換鈕和旗標:
- _global_killswitch:所有 ODP 功能的全局切換;設為 false 即可使用 ODP
- _federated_compute_kill_switch:_控制 ODP 所有訓練 (聯邦學習) 功能的切換鈕;設為 false 即可使用訓練功能
- _caller_app_allowlist:控管允許呼叫 ODP 的對象,可在此新增應用程式 (套件名稱,[選用] 憑證),或設為 * 以允許所有對象
- _isolated_service_allowlist:控管哪些服務可在 Isolated Service 程序中執行。
您可以執行下列指令,設定所有交換器和標記,以便不受限制地使用 ODP:
# 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
請參閱 ODP 的 Android API 參考說明文件。
與「IsolatedService」的互動
IsolatedService 類別是抽象基底類別,所有打算根據 ODP 開發的開發人員都必須擴充這個類別,並在套件資訊清單中宣告這個類別在獨立程序中執行。ODP 服務會在獨立程序中啟動這項服務,並向其提出要求。IsolatedService 會接收 ODP 服務的要求,並建立 IsolatedWorker 來處理要求。
開發人員必須實作 IsolatedWorker 介面的方法,才能處理用戶端應用程式要求、下載完成事件,以及轉譯 HTML 觸發的事件。所有這些方法都有預設的免人工管理實作項目,因此開發人員可以略過他們不感興趣的方法。
OnDevicePersonalizationManager 類別提供 API,供應用程式和 SDK 與開發人員導入的 IsolatedService 互動,該 IsolatedService 會在獨立程序中執行。以下列出一些預期用途:
產生要在 SurfaceView 中顯示的 HTML 內容
如要生成要顯示的內容,呼叫應用程式可以使用後續 requestSurfacePackage 呼叫中傳回的 SurfacePackageToken 物件,要求在 SurfaceView 中算繪結果。OnDevicePersonalizationManager#execute
成功後,系統會呼叫接收器,並提供 ODP 服務算繪的 View 的 SurfacePackage。用戶端應用程式需要在 View 階層的 SurfaceView 中插入 SurfacePackage。
當應用程式使用先前 OnDevicePersonalizationManager#execute 呼叫傳回的 SurfacePackageToken 進行 requestSurfacePackage 呼叫時,ODP 服務會呼叫 IsolatedWorker#onRender,擷取要在設限框架中轉譯的 HTML 片段。在此階段,開發人員無法存取 LocalData 或 UserData。這樣一來,開發人員就不會在產生的 HTML 中,將可能含有私密資訊的 UserData 嵌入素材資源擷取網址。開發人員可以使用 IsolatedService#getEventUrlProvider 產生追蹤網址,並加入產生的 HTML 中。轉譯 HTML 時,ODP 服務會攔截傳送至這些網址的要求,並呼叫 IsolatedWorker#onEvent。實作 onRender() 時,可以叫用 getRemoteData()。
追蹤 HTML 內容中的事件
EventUrlProvider 類別提供 API,可產生開發人員可能會納入 HTML 輸出的事件追蹤網址。HTML 轉譯時,ODP 會使用事件網址的酬載叫用 IsolatedWorker#onEvent。
ODP 服務會攔截轉譯 HTML 中傳送至 ODP 產生事件網址的要求、呼叫 IsolatedWorker#onEvent,並將傳回的 EventLogRecord 記錄在 EVENTS 資料表中。
寫入永久結果
使用 OnDevicePersonalizationManager#execute,服務可選擇將資料寫入永久儲存空間 (REQUESTS 和 EVENTS 資料表)。以下是可寫入這些表格的項目:
- 要新增至
REQUESTS資料表的RequestLogRecord。 - 要新增至
EVENTS資料表的EventLogRecord物件清單,每個物件都包含先前寫入的RequestLogRecord指標。
裝置端儲存空間中的永久結果可供聯合學習用於模型訓練。
管理裝置端訓練工作
當聯合運算訓練工作開始,且 ODP 服務想取得採用 ODP 的開發人員提供的訓練範例時,就會呼叫 IsolatedWorker#onTrainingExample。實作 onTrainingExample() 時,您可以叫用 getRemoteData()、getLocalData()、getUserData() 和 getLogReader()。
如要排定或取消聯合運算工作,可以使用 FederatedComputeScheduler 類別,這個類別會提供所有 ODP IsolatedService 的 API。每個聯邦運算作業都可以透過母體名稱識別。
排定新的聯合運算工作前,請先完成下列事項:
- 遠端聯合運算伺服器上應已建立具有這個族群名稱的任務。
- 套件資訊清單設定中應已使用
federated-compute-settings標記指定聯合運算伺服器網址端點。
與持續性輸出內容互動
下一節說明如何在 ODP 中與持續性輸出內容互動。
讀取本機資料表
LogReader 類別提供 API,可讀取 REQUESTS 和 EVENTS 資料表。這些資料表包含 IsolatedService 在 onExecute() 或 onEvent() 呼叫期間寫入的資料。這些表格中的資料可用於聯合學習輔助模型訓練,或聯合分析輔助跨裝置統計分析。
與下載內容互動
下一節說明如何在 ODP 中與下載的內容互動。
從伺服器下載內容
ODP 服務會定期從 IsolatedService 的套件資訊清單中宣告的網址下載內容,並在下載完成後呼叫 onDownloadCompleted。下載的檔案是包含鍵/值組合的 JSON 檔案。
採用 ODP 的開發人員可以選擇要將下載內容的哪個子集新增至 RemoteData 表格,以及要捨棄哪些內容。開發人員無法修改下載的內容,確保 RemoteData 表格不含任何使用者資料。此外,開發人員可自由選擇要填入 LocalData 表格的內容,例如快取部分預先計算的結果。
下載要求格式
ODP 會定期輪詢開發人員套件資訊清單中宣告的網址端點,擷取內容來填入 RemoteData 表格。
端點應會傳回 JSON 回應,詳情請見下文。JSON 回應必須包含 syncToken,用來識別傳送的資料版本,以及要填入的鍵/值組合清單。syncToken 值必須是以秒為單位的時間戳記,且必須以世界標準時間為準。在下載要求中,ODP 會提供先前完成下載作業的 syncToken,以及裝置國家/地區,做為下載網址中的 syncToken 和 country 參數。伺服器可以使用先前的 syncToken 實作增量下載。
下載檔案格式
下載的檔案是 JSON 檔案,結構如下。JSON 檔案應包含 syncToken,用於識別要下載的資料版本。syncToken 必須是 UTC 時間戳記,且必須限制在小時界限內,並超過先前下載的 syncToken。如果 syncToken 不符合這兩項規定,系統會捨棄下載的內容,不會進行處理。
內容欄位是 (鍵、資料、編碼) 元組的清單。key 應為 UTF-8 字串。encoding 欄位是選用參數,用於指定 data 欄位的編碼方式,可設為「utf8」或「base64」,預設為「utf8」。在呼叫 onDownloadCompleted(). 之前,key 欄位會轉換為 String 物件,data 欄位則會轉換為位元組陣列。
{
// 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
本節說明如何與聯邦運算伺服器 API 互動。
Federated Compute Server API
如要在用戶端排定聯合運算工作,您需要遠端聯合運算伺服器上建立的任務,並提供母體名稱。本節將說明如何在聯合運算伺服器上建立這類工作。
為工作建立工具建立新工作時,ODP 開發人員應提供兩組檔案:
- 透過呼叫 tff.learning.models.save_functional_model API 呼叫儲存的 tff.learning.models.FunctionalModel 模型。您可以在 GitHub 存放區中找到一個範例。
- fcp_server_config.json,其中包含政策、聯合學習設定和差異化隱私設定。以下是 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
}
}
如需更多範例,請前往 GitHub 存放區。
準備好這兩項輸入內容後,請叫用 Task Builder 建構構件並生成新工作。如需更詳細的操作說明,請前往 GitHub 存放區。