Path: blob/master/site/ko/federated/tutorials/sparse_federated_learning.ipynb
25118 views
Copyright 2021 The TensorFlow Federated Authors.
federated_select
및 희소 집계를 통한 클라이언트 효율적 대형 모델 페더레이션 학습
이 튜토리얼은 각 클라이언트 장치가 tff.federated_select
및 희소 집계를 사용하여 모델의 작은 부분만 다운로드하고 업데이트하는 매우 큰 모델을 훈련하는 데 TFF를 사용할 수 있는 방법을 보여줍니다. 이 튜토리얼은 상당히 독립적이지만, tff.federated_select
튜토리얼과 사용자 정의 FL 알고리즘 튜토리얼은 여기에 사용된 몇 가지 기술에 대한 좋은 소개 정보를 제공합니다.
구체적으로, 이 튜토리얼에서는 bag-of-words 기능 표현을 기반으로 텍스트 문자열과 연결된 "태그"를 예측하는 다중 레이블 분류를 위해 로지스틱 회귀를 고려합니다. 중요한 것은 통신 및 클라이언트 측 계산 비용이 고정 상수(MAX_TOKENS_SELECTED_PER_CLIENT
)에 의해 제어되고 실제 환경에서 매우 클 수 있는 전체 어휘 크기로 확장되지 않는다는 것입니다.
각 클라이언트는 기껏해야 이 정도로 많은 고유 토큰에 대한 모델 가중치 행을 federated_select
처리합니다. 이것은 클라이언트의 로컬 모델 크기와 수행된 서버 -> 클라이언트(federated_select
) 및 클라이언트 - > 서버(federated_aggregate
) 통신 양에 대한 상한을 결정합니다.
이 튜토리얼은 이를 1만큼 작게 설정하거나(각 클라이언트의 모든 토큰이 선택되지 않도록 함) 큰 값으로 설정하더라도 올바르게 실행되어야 하지만 모델 수렴이 영향을 받을 수 있습니다.
또한 다양한 유형에 대해 몇 가지 상수를 정의합니다. 이 colab의 경우 토큰은 데이터세트를 구문 분석한 후 특정 단어에 대한 정수 식별자입니다.
문제 설정: 데이터세트 및 모델
이 튜토리얼에서는 쉽게 실험할 수 있도록 작은 장난감 데이터세트를 구성합니다. 그러나 데이터세트의 형식은 Federated StackOverflow와 호환되며 전처리 및 모델 아키텍처는 적응형 페더레이션 최적화의 StackOverflow 태그 예측 문제에서 채택되었습니다.
데이터세트 구문 분석 및 전처리
작은 장난감 데이터세트
12개의 단어로 구성된 글로벌 어휘와 3명의 클라이언트가 있는 작은 장난감 데이터세트를 구성합니다. 이 작은 예제는 엣지 케이스를 테스트하고(예를 들어, MAX_TOKENS_SELECTED_PER_CLIENT = 6
미만의 고유 토큰을 가진 두 클라이언트와 그 이상을 가진 클라이언트가 있는 경우) 코드를 개발하는 데 유용합니다.
그러나 이 접근 방식의 실제 사용 사례는 수천만 개 이상의 글로벌 어휘가 될 것이며 각 클라이언트에 아마도 수천 개의 고유한 토큰이 나타날 것입니다. 데이터 형식이 동일하기 때문에 tff.simulation.datasets.stackoverflow.load_data()
데이터세트와 같은 보다 현실적인 테스트베드 문제로 확장하는 과정은 간단합니다.
먼저, 단어와 태그 어휘를 정의합니다.
이제, 작은 로컬 데이터세트로 3개의 클라이언트를 생성합니다. colab에서 이 튜토리얼을 실행하는 경우 아래 개발된 함수의 출력을 해석/확인하기 위해 "탭에서 셀 미러링" 기능을 사용하여 이 셀과 해당 출력을 고정하는 것이 유용할 수 있습니다.
입력 요소(토큰/단어) 및 레이블(사후 태그)의 원시 수에 대한 상수를 정의합니다. 실제 입력/출력 공간은 OOV 토큰/태그를 추가하므로 NUM_OOV_BUCKETS = 1
더 큽니다.
데이터세트의 배치 버전과 개별 배치를 생성하면 코드를 테스트하는 데 유용할 것입니다.
희소 입력으로 모델 정의하기
각 태그에 대해 간단한 독립 로지스틱 회귀 모델을 사용합니다.
먼저 예측을 수행하여 제대로 작동하는지 확인합시다.
그리고 몇 가지 간단한 중앙 집중식 훈련:
페더레이션 계산을 위한 빌딩 블록
각 장치가 모델의 관련 하위 집합만 다운로드하고 해당 하위 집합에 대한 업데이트만 제공한다는 주된 차이를 두고 간단한 버전의 페더레이션 평균화 알고리즘을 구현하겠습니다.
MAX_TOKENS_SELECTED_PER_CLIENT
의 단축형으로 M
을 사용합니다. 높은 수준에서 한 라운드의 훈련에는 다음과 같은 단계가 포함됩니다:
참여하는 각 클라이언트는 로컬 데이터세트를 검색하여 입력 문자열을 구문 분석하고 이를 올바른 토큰(int 인덱스)에 매핑합니다. 이를 위해서는 전역(대형) 사전에 대한 액세스가 필요합니다(이는 기능 해싱 기술을 사용하여 잠재적으로 피할 수 있음). 그런 다음 각 토큰이 발생하는 횟수를 드물게 계산합니다. 장치에서
U
의 고유한 토큰이 발생하는 경우num_actual_tokens = min(U, M)
개의 가장 빈번한 토큰의 훈련을 선택합니다.클라이언트는
federated_select
를 사용하여 서버에서num_actual_tokens
개의 선택된 토큰에 대한 모델 계수를 가져옵니다. 각 모델 슬라이스는(TAG_VOCAB_SIZE, )
모양의 텐서이므로 클라이언트에 전송되는 총 데이터의 크기는 최대TAG_VOCAB_SIZE * M
입니다(아래 참고 참조).클라이언트는 매핑
global_token -> local_token
을 구성합니다. 여기서 로컬 토큰(int 인덱스)은 선택한 토큰 목록에 있는 글로벌 토큰의 인덱스입니다.클라이언트는
[0, num_actual_tokens)
범위에서 최대M
개의 토큰에 대한 계수만 있는 글로벌 모델의 "소규모" 버전을 사용합니다.global -> local
매핑은 선택한 모델 조각에서 이 모델의 밀집 매개변수를 초기화하는 데 사용됩니다.클라이언트는
global -> local
매핑으로 사전 처리된 데이터에서 SGD를 사용하여 로컬 모델을 훈련합니다.클라이언트는 행을 인덱싱하기 위해
local -> global
매핑을 사용하여 로컬 모델의 매개변수를IndexedSlices
업데이트로 바꿉니다. 서버는 희소 합계 집계를 사용하여 이러한 업데이트를 집계합니다.서버는 위 집계의 (밀집) 결과를 가져와서 참여하는 클라이언트 수로 나누고 결과적인 평균 업데이트를 글로벌 모델에 적용합니다.
이 섹션에서는 이러한 단계를 위한 빌딩 블록을 구성한 다음, 한 번의 전체 훈련 라운드 논리를 캡처하는 최종 federated_computation
에서 결합합니다.
참고: 위의 설명에는 한 가지 기술적인 정보가 숨겨져 있습니다.
federated_select
와 로컬 모델 구성 모두에 정적으로 알려진 형상이 필요하므로 동적 클라이언트별num_actual_tokens
크기를 사용할 수 없습니다. 대신, 정적 값M
을 사용하여 필요한 경우 패딩을 추가합니다. 이것은 알고리즘의 의미에 영향을 미치지 않습니다.
클라이언트 토큰을 계산하고 federated_select
할 모델 조각 결정하기
각 장치는 모델의 어떤 "슬라이스"가 로컬 훈련 데이터세트와 관련이 있는지 결정해야 합니다. 본 문제의 경우 클라이언트 훈련 데이터세트의 각 토큰이 포함된 예제의 수를 (희소하게!) 계산하여 이 작업을 수행합니다.
장치에서 가장 자주 발생하는 MAX_TOKENS_SELECTED_PER_CLIENT
토큰에 해당하는 모델 매개변수를 선택합니다. 장치에서 이보다 적은 수의 토큰이 발생하면 federated_select
를 사용할 수 있도록 목록을 패딩합니다.
예를 들어 토큰을 무작위로 선택하는 것과 같은 다른 전략이 더 나을 수 있다는 점에 유의하십시오(발생 확률에 따라). 이렇게 하면 클라이언트에 데이터가 있는 모델의 모든 조각이 업데이트될 가능성이 있습니다.
글로벌 토큰을 로컬 토큰에 매핑하기
위의 선택은 온디바이스 모델에 사용할 [0, actual_num_tokens)
범위의 밀집된 토큰 세트를 제공합니다. 그러나 우리가 읽은 데이터세트에는 훨씬 더 큰 글로벌 어휘 범위인 [0, WORD_VOCAB_SIZE)
의 토큰이 있습니다.
따라서 글로벌 토큰을 해당 로컬 토큰에 매핑해야 합니다. 로컬 토큰 ID는 이전 단계에서 계산된 selected_tokens
텐서에 대한 인덱스에 의해 간단히 제공됩니다.
각 클라이언트에서 로컬(하위) 모델 훈련하기
federated_select
는 선택한 슬라이스를 선택 키와 동일한 순서로 tf.data.Dataset
로 반환합니다. 따라서 먼저 이러한 데이터세트를 가져와서 클라이언트 모델의 모델 가중치로 사용할 수 있는 단일 밀도 텐서로 변환하는 유틸리티 함수를 정의합니다.
이제 각 클라이언트에서 실행할 간단한 로컬 훈련 루프를 정의하는 데 필요한 모든 구성 요소가 준비되었습니다.
IndexedSlice 집계하기
IndexedSlices
에 대한 페더레이션 희소 합계를 구성하기 위해 tff.federated_aggregate
를 사용합니다. 이 간단한 구현에는 dense_shape
가 사전에 정적으로 알려진다는 제약이 있습니다. 또한 이 합계는 클라이언트 -> 서버 통신이 희소하지만 서버는 accumulate
및 merge
에서 합계의 밀집된 표현을 유지관리하고 이 밀집된 표현을 출력한다는 점에서 단지 반희소입니다.
테스트로 최소 federated_computation
을 구성합니다.
federated_computation
에 모두 결합하기
이제 TFF를 사용하여 구성 요소를 tff.federated_computation
으로 결합합니다.
페더레이션 평균화 기반의 기본 서버 훈련 함수를 사용하여 서버 학습률 1.0으로 업데이트를 적용합니다. 클라이언트가 제공한 모델을 단순히 평균화하는 대신 모델에 업데이트(델타)를 적용하는 것이 중요합니다. 그렇지 않으면 주어진 모델 슬라이스가 주어진 라운드에 클라이언트에 의해 훈련되지 않으면 계수가 0이 될 수 있기 때문입니다.
몇 가지 tff.tf_computation
구성 요소가 더 필요합니다.
이제 모든 조각을 결합할 준비가 되었습니다!
모델을 훈련시켜 보겠습니다!
이제 훈련 함수가 생겼으니 시도해 보겠습니다.