Tham dự Hội nghị chuyên đề Women in ML vào ngày 7 tháng 12 Đăng ký ngay

Lõi liên kết

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Tài liệu này giới thiệu lớp cốt lõi của TFF dùng làm nền tảng cho Học liên kết và các thuật toán liên kết không học có thể có trong tương lai.

Để có phần giới thiệu nhẹ nhàng về Federated Core, vui lòng đọc các hướng dẫn sau, vì chúng giới thiệu một số khái niệm cơ bản bằng ví dụ và minh họa từng bước việc xây dựng một thuật toán tính trung bình liên kết đơn giản.

Chúng tôi cũng khuyến khích bạn tự làm quen với Học liên kết và các hướng dẫn liên quan về phân loại hình ảnhtạo văn bản , vì việc sử dụng API cốt lõi liên kết (FC API) để học liên kết cung cấp ngữ cảnh quan trọng cho một số lựa chọn mà chúng tôi đã đưa ra thiết kế lớp này.

Tổng quan

Mục tiêu, Mục đích sử dụng và Phạm vi

Federated Core (FC) được hiểu rõ nhất là một môi trường lập trình để thực hiện các phép tính phân tán, tức là các phép tính liên quan đến nhiều máy tính (điện thoại di động, máy tính bảng, thiết bị nhúng, máy tính để bàn, cảm biến, máy chủ cơ sở dữ liệu, v.v.) mà mỗi máy tính có thể thực hiện không xử lý cục bộ tầm thường và giao tiếp trên mạng để điều phối công việc của họ.

Thuật ngữ phân phối rất chung chung và TFF không nhắm mục tiêu tất cả các loại thuật toán phân tán có thể có ngoài đó, vì vậy chúng tôi thích sử dụng thuật ngữ tính toán liên hợp ít chung chung hơn để mô tả các loại thuật toán có thể được biểu thị trong khuôn khổ này.

Mặc dù việc xác định thuật ngữ tính toán liên hợp theo cách hoàn toàn chính thức nằm ngoài phạm vi của tài liệu này, hãy nghĩ đến các loại thuật toán bạn có thể thấy được thể hiện bằng mã giả trong một ấn phẩm nghiên cứu mô tả một thuật toán học phân tán mới.

Tóm lại, mục tiêu của FC là cho phép biểu diễn nhỏ gọn tương tự, ở mức trừu tượng giống mã giả tương tự, của logic chương trình không phải là mã giả, mà đúng hơn, nó có thể thực thi trong nhiều môi trường đích.

Đặc điểm xác định chính của các loại thuật toán mà FC được thiết kế để thể hiện là các hành động của những người tham gia hệ thống được mô tả theo cách thức tập thể. Do đó, chúng ta có xu hướng nói về từng thiết bị chuyển đổi dữ liệu cục bộ và các thiết bị điều phối hoạt động bởi một điều phối viên tập trung phát sóng , thu thập hoặc tổng hợp kết quả của chúng.

Trong khi TFF đã được thiết kế để có thể vượt ra ngoài các kiến ​​trúc máy khách-máy chủ đơn giản, khái niệm xử lý tập thể là cơ bản. Điều này là do nguồn gốc của TFF trong học tập liên kết, một công nghệ ban đầu được thiết kế để hỗ trợ tính toán trên dữ liệu nhạy cảm tiềm ẩn vẫn nằm trong tầm kiểm soát của các thiết bị khách và có thể không chỉ được tải xuống một vị trí tập trung vì lý do bảo mật. Mặc dù mỗi khách hàng trong các hệ thống như vậy đóng góp dữ liệu và khả năng xử lý theo hướng tính toán kết quả của hệ thống (kết quả mà chúng tôi thường mong đợi là có giá trị cho tất cả những người tham gia), chúng tôi cũng cố gắng duy trì sự riêng tư và ẩn danh của mỗi khách hàng.

Do đó, trong khi hầu hết các khuôn khổ cho máy tính phân tán được thiết kế để thể hiện quá trình xử lý từ quan điểm của từng người tham gia - nghĩa là, ở cấp độ trao đổi thông điệp điểm-điểm cá nhân và sự phụ thuộc lẫn nhau của các chuyển đổi trạng thái cục bộ của người tham gia với các thông điệp đến và đi , Lõi liên kết của TFF được thiết kế để mô tả hành vi của hệ thống từ quan điểm toàn hệ thống (tương tự như MapReduce ).

Do đó, trong khi các khuôn khổ phân tán cho các mục đích chung có thể cung cấp các hoạt động như gửinhận dưới dạng khối xây dựng, FC cung cấp các khối xây dựng như tff.federated_sum , tff.federated_reduce hoặc tff.federated_broadcast đóng gói các giao thức phân tán đơn giản.

Ngôn ngữ

Giao diện Python

TFF sử dụng ngôn ngữ nội bộ để biểu diễn các phép tính liên hợp, cú pháp của nó được xác định bằng biểu diễn có thể tuần tự hóa trong computation.proto . Tuy nhiên, người dùng FC API nói chung sẽ không cần phải tương tác trực tiếp với ngôn ngữ này. Thay vào đó, chúng tôi cung cấp một API Python (không gian tên tff ) bao bọc xung quanh nó như một cách để xác định các phép tính.

Cụ thể, TFF cung cấp các trình trang trí hàm Python như tff.federated_computation để theo dõi các phần thân của các hàm được trang trí và tạo ra các biểu diễn tuần tự của logic tính toán liên hợp bằng ngôn ngữ của TFF. Một hàm được trang trí bằng tff.federated_computation hoạt động như một vật mang biểu diễn tuần tự như vậy và có thể nhúng nó như một khối xây dựng trong phần thân của một phép tính khác hoặc thực thi nó theo yêu cầu khi được gọi.

Đây chỉ là một ví dụ; có thể tìm thấy nhiều ví dụ hơn trong hướng dẫn thuật toán tùy chỉnh .

@tff.federated_computation(tff.type_at_clients(tf.float32))
def get_average_temperature(sensor_readings):
  return tff.federated_mean(sensor_readings)

Người đọc quen thuộc với TensorFlow không háo hức sẽ thấy cách tiếp cận này tương tự như cách viết mã Python sử dụng các hàm như tf.add hoặc tf.reduce_sum trong một phần mã Python xác định đồ thị TensorFlow. Mặc dù về mặt kỹ thuật, mã được thể hiện bằng Python, nhưng mục đích của nó là tạo ra một biểu diễn có thể tuần tự hóa của một tf.Graph bên dưới và đó là biểu đồ, không phải mã Python, được thực thi nội bộ bởi thời gian chạy TensorFlow. Tương tự như vậy, người ta có thể nghĩ về tff.federated_mean như việc chèn một op liên kết vào một phép tính liên kết được đại diện bởi get_average_temperature .

Một phần lý do khiến FC xác định ngôn ngữ liên quan đến thực tế là, như đã lưu ý ở trên, các phép tính liên hợp chỉ định các hành vi tập thể phân tán và do đó, logic của chúng là không cục bộ. Ví dụ, TFF cung cấp các nhà khai thác, đầu vào và đầu ra của chúng có thể tồn tại ở những nơi khác nhau trong mạng.

Điều này đòi hỏi một ngôn ngữ và một hệ thống kiểu nắm bắt được khái niệm về tính phân tán.

Loại hệ thống

Federated Core cung cấp các loại loại sau. Khi mô tả các kiểu này, chúng tôi chỉ đến các hàm tạo kiểu cũng như giới thiệu một ký hiệu nhỏ gọn, vì đó là một cách tiện dụng hoặc mô tả các kiểu tính toán và toán tử.

Đầu tiên, đây là danh mục các loại tương tự về mặt khái niệm với các loại được tìm thấy trong các ngôn ngữ chính thống hiện có:

  • Các kiểu căng ( tff.TensorType ). Cũng như trong TensorFlow, chúng có dtypeshape . Sự khác biệt duy nhất là các đối tượng thuộc loại này không bị giới hạn ở các tf.Tensor trong Python biểu thị kết quả đầu ra của các hoạt động TensorFlow trong biểu đồ TensorFlow, nhưng cũng có thể bao gồm các đơn vị dữ liệu có thể được tạo ra, ví dụ: dưới dạng đầu ra của một giao thức tổng hợp. Do đó, kiểu tensor TFF chỉ đơn giản là một phiên bản trừu tượng của một biểu diễn vật lý cụ thể của kiểu như vậy trong Python hoặc TensorFlow.

    TensorTypes của TFF có thể xử lý hình dạng (tĩnh) chặt chẽ hơn TensorFlow. Ví dụ, hệ thống sắp chữ của TFF coi một tensor có thứ hạng không xác định là có thể gán từ bất kỳ tensor nào khác cùng dtype , nhưng không thể gán cho bất kỳ tensor nào có thứ hạng cố định. Phương pháp xử lý này ngăn chặn một số lỗi thời gian chạy nhất định (ví dụ: cố gắng định hình lại một tensor có thứ hạng không xác định thành một hình dạng có số phần tử không chính xác), với cái giá phải trả là sự nghiêm ngặt hơn trong những gì tính toán mà TFF chấp nhận là hợp lệ.

    Kí hiệu nhỏ gọn cho các loại tensor là dtype hoặc dtype[shape] . Ví dụ, int32int32[10] lần lượt là kiểu số nguyên và vectơ int.

  • Các kiểu trình tự ( tff.SequenceType ). Đây là những tương đương trừu tượng của TFF với khái niệm cụ thể của TensorFlow về tf.data.Dataset s. Các phần tử của chuỗi có thể được tiêu thụ theo cách tuần tự, và có thể bao gồm các loại phức tạp.

    Biểu diễn thu gọn của các kiểu dãy là T* , trong đó T là kiểu của các phần tử. Ví dụ int32* đại diện cho một dãy số nguyên.

  • Các loại tuple được đặt tên ( tff.StructType ). Đây là cách TFF xây dựng các bộ giá trị và các cấu trúc giống như từ điển có một số phần tử được xác định trước với các kiểu cụ thể, có tên hoặc không tên. Quan trọng là, khái niệm tuple được đặt tên của TFF bao gồm tương đương trừu tượng của các bộ đối số của Python, tức là tập hợp các phần tử trong đó một số, nhưng không phải tất cả đều được đặt tên và một số có vị trí.

    Ký hiệu nhỏ gọn cho các bộ giá trị được đặt tên là <n_1=T_1, ..., n_k=T_k> , trong đó n_k là tên phần tử tùy chọn và T_k là loại phần tử. Ví dụ: <int32,int32> là một ký hiệu nhỏ gọn cho một cặp số nguyên không được đặt tên và <X=float32,Y=float32> là một ký hiệu nhỏ gọn cho một cặp float có tên XY có thể đại diện cho một điểm trên mặt phẳng . Các bộ giá trị có thể được lồng vào nhau cũng như trộn lẫn với các loại khác, ví dụ: <X=float32,Y=float32>* sẽ là một ký hiệu nhỏ gọn cho một chuỗi các điểm.

  • Các kiểu hàm ( tff.FunctionType ). TFF là một khung lập trình chức năng, với các chức năng được coi là giá trị hạng nhất . Các hàm có nhiều nhất một đối số và chính xác một kết quả.

    Ký hiệu thu gọn cho các hàm là (T -> U) , trong đó T là kiểu của đối số và U là kiểu của kết quả hoặc ( -> U) nếu không có đối số (mặc dù các hàm không có đối số là suy biến khái niệm hầu như chỉ tồn tại ở cấp Python). Ví dụ (int32* -> int32) là một ký hiệu cho một loại hàm làm giảm một chuỗi số nguyên thành một giá trị số nguyên duy nhất.

Các loại sau giải quyết khía cạnh hệ thống phân tán của tính toán TFF. Vì những khái niệm này hơi độc đáo đối với TFF, chúng tôi khuyến khích bạn tham khảo hướng dẫn thuật toán tùy chỉnh để có thêm bình luận và ví dụ.

  • Loại vị trí . Loại này chưa được hiển thị trong API công khai ngoài dạng 2 chữ tff.SERVERtff.CLIENTS mà bạn có thể coi là các hằng của loại này. Tuy nhiên, nó được sử dụng nội bộ và sẽ được giới thiệu trong API công khai trong các bản phát hành trong tương lai. Đại diện nhỏ gọn của loại này là placement .

    Một vị trí đại diện cho một tập thể những người tham gia hệ thống đóng một vai trò cụ thể. Bản phát hành ban đầu đang nhắm mục tiêu đến các tính toán máy khách-máy chủ, trong đó có 2 nhóm người tham gia: máy kháchmáy chủ (bạn có thể coi nhóm sau là một nhóm singleton). Tuy nhiên, trong các kiến ​​trúc phức tạp hơn, có thể có các vai trò khác, chẳng hạn như trình tổng hợp trung gian trong hệ thống nhiều tầng, người có thể thực hiện các kiểu tổng hợp khác nhau hoặc sử dụng các kiểu nén / giải nén dữ liệu khác với kiểu được sử dụng bởi máy chủ hoặc các khách hàng.

    Mục đích chính của việc xác định khái niệm vị trí là làm cơ sở để xác định các loại liên kết .

  • Các kiểu liên kết ( tff.FederatedType ). Giá trị của kiểu liên kết là giá trị được lưu trữ bởi một nhóm người tham gia hệ thống được xác định bởi một vị trí cụ thể (chẳng hạn như tff.SERVER hoặc tff.CLIENTS ). Loại liên kết được xác định bởi giá trị vị trí (do đó, nó là một loại phụ thuộc ), loại thành viên (loại nội dung mà mỗi người tham gia lưu trữ cục bộ) và bit bổ sung all_equal chỉ định xem tất cả người tham gia có phải là người cục bộ hay không lưu trữ cùng một mục.

    Ký hiệu nhỏ gọn cho loại giá trị được liên kết bao gồm các mục (cấu thành thành viên) thuộc loại T , mỗi mục được lưu trữ bởi nhóm (vị trí) GT@G hoặc {T}@G với bit all_equal được đặt hoặc không được đặt, tương ứng.

    Ví dụ:

    • {int32}@CLIENTS đại diện cho một giá trị được liên kết bao gồm một tập hợp các số nguyên có khả năng khác biệt, một số cho mỗi thiết bị khách. Lưu ý rằng chúng ta đang nói về một giá trị liên kết đơn lẻ bao gồm nhiều mục dữ liệu xuất hiện ở nhiều vị trí trên toàn mạng. Một cách để nghĩ về nó là như một loại tensor có kích thước "mạng", mặc dù sự tương tự này không hoàn hảo vì TFF không cho phép truy cập ngẫu nhiên vào các thành phần thành viên của một giá trị liên kết.

    • {<X=float32,Y=float32>*}@CLIENTS đại diện cho tập dữ liệu được liên kết , một giá trị bao gồm nhiều chuỗi tọa độ XY , một chuỗi cho mỗi thiết bị khách.

    • <weights=float32[10,5],bias=float32[5]>@SERVER đại diện cho một bộ giá trị trọng số và độ phân vị được đặt tên tại máy chủ. Vì chúng ta đã bỏ dấu ngoặc nhọn, điều này cho biết bit all_equal đã được đặt, tức là chỉ có một bộ giá trị duy nhất (bất kể có bao nhiêu bản sao máy chủ có thể có trong một cụm lưu trữ giá trị này).

Khu nhà

Ngôn ngữ của Federated Core là một dạng giải tích lambda , với một vài yếu tố bổ sung.

Nó cung cấp các phần tóm tắt lập trình sau đây hiện được hiển thị trong API công khai:

  • Tính toán TensorFlow ( tff.tf_computation ). Đây là các phần của mã TensorFlow được bao bọc dưới dạng các thành phần có thể tái sử dụng trong TFF bằng cách sử dụng trình trang trí tff.tf_computation . Chúng luôn có các loại chức năng và không giống như các hàm trong TensorFlow, chúng có thể nhận các tham số có cấu trúc hoặc trả về kết quả có cấu trúc của một loại trình tự.

    Đây là một ví dụ, phép tính TF kiểu (int32* -> int) sử dụng toán tử tf.data.Dataset.reduce để tính tổng các số nguyên:

    @tff.tf_computation(tff.SequenceType(tf.int32))
    def add_up_integers(x):
      return x.reduce(np.int32(0), lambda x, y: x + y)
    
  • Các toán tử nội tại hoặc liên kết ( tff.federated_... ). Đây là thư viện các hàm như tff.federated_sum hoặc tff.federated_broadcast cấu thành phần lớn FC API, hầu hết chúng đại diện cho các toán tử truyền thông phân tán để sử dụng với TFF.

    Chúng tôi gọi chúng là các hàm bản chất bởi vì, phần nào giống như các hàm nội tại , chúng là một tập hợp các toán tử mở, có thể mở rộng được TFF hiểu và được biên dịch thành mã cấp thấp hơn.

    Hầu hết các toán tử này có các tham số và kết quả của các kiểu liên kết và hầu hết là các mẫu có thể được áp dụng cho các loại dữ liệu khác nhau.

    Ví dụ: tff.federated_broadcast có thể được coi là toán tử mẫu của loại chức năng T@SERVER -> T@CLIENTS .

  • Biểu thức Lambda ( tff.federated_computation ). Biểu thức lambda trong TFF tương đương với lambda hoặc def trong Python; nó bao gồm tên tham số và nội dung (biểu thức) có chứa các tham chiếu đến tham số này.

    Trong mã Python, chúng có thể được tạo bằng cách trang trí các hàm Python với tff.federated_computation và xác định một đối số.

    Đây là một ví dụ về biểu thức lambda mà chúng tôi đã đề cập trước đó:

    @tff.federated_computation(tff.type_at_clients(tf.float32))
    def get_average_temperature(sensor_readings):
      return tff.federated_mean(sensor_readings)
    
  • Các ký tự vị trí . Hiện tại, chỉ có tff.SERVERtff.CLIENTS cho phép xác định các tính toán máy chủ-máy khách đơn giản.

  • Lệnh gọi hàm ( __call__ ). Bất kỳ thứ gì có kiểu chức năng đều có thể được gọi bằng cú pháp Python __call__ chuẩn. Lời gọi là một biểu thức, kiểu của nó giống như kiểu của kết quả của hàm đang được gọi.

    Ví dụ:

    • add_up_integers(x) đại diện cho một lệnh gọi tính toán TensorFlow được xác định trước đó trên một đối số x . Kiểu của biểu thức này là int32 .

    • tff.federated_mean(sensor_readings) đại diện cho một lệnh gọi của toán tử trung bình liên kết trên sensor_readings . Kiểu của biểu thức này là float32@SERVER (giả sử ngữ cảnh từ ví dụ trên).

  • Hình thành các bộ giá trịchọn các phần tử của chúng. Biểu thức Python có dạng [x, y] , x[y] hoặc xy xuất hiện trong phần thân của các hàm được trang trí bằng tff.federated_computation .