Вводно распределительные устройства: Вводно распределительные устройства ВРУ, УВР

Содержание

вру 1-2-3. вводно-распределительные устройства

Электротехнический завод «СлавЭнерго» производит вводно-распределительные устройства ВРУ (1,2,3), вру 8504 для приема, учета и распределения электрической энергии напряжением 0,4/0,23 кВ и частотой 50/60 Гц.

НАЗНАЧЕНИЕ

Щиты ВРУ широко применяются для промышленных и домовых вводно-распределительных нужд в трехфазных сетях низкого напряжения. Помимо приема и распределения электроэнергии выполняют защитную роль от перегрузок и коротких замыканий, а также выполняют роль инструмента нечастых коммутаций электрооборудования (включения/отключения).

КОНСТРУКЦИЯ И КОМПЛЕКТАЦИЯ

Вводно-распределительные устройства изготавливаются напольного или навесного исполнения. Шкафы ВРУ, как правило, имеют разделение на одну или две панели с компонентами приема электроэнергии, такими как вводные разъединители или переключатели, предохранительные группы и сборные шины, а также панели учета электроэнергии со счетчиками,измерительными трансформаторами и компонентами вывода. Панель учета имеет место для пломбировки. В отдельных случаях ВРУ-1 (2,3) могут оснащаться специальными автоматами и фоточувствительными выключателями внутреннего освещения, а также компонентами АВР (автоматического ввода резерва). Сборка ВРУ 8504 и других щитов осуществляется на основе качественных европейских компонентов, в шкафах из листовой стали 1-1,2 мм., с соблюдением всех стандартов качества. Шкафы имеют порошковую окраску цветового диапазона RAL 7032/7035 по выбору заказчика и степень защиты от IP 21 до IP 54.

скачать опросный лист

Обратите внимание, доставка в Москву осуществляется бесплатно! Доставка в регионы России по минимальным ценам! Информация по доставке в регионы

ЗАКАЗ ВРУ

Для заказа ВРУ необходимо предоставить в отдел продажили через форму связи: *

  • Однолинейную схему устройства
  • Компонентную спецификацию устройства
  • Габаритно-установочные размеры

* При заказе ВРУ комплектно сконденсаторными установкамидействуют специальные цены

СТРУКТУРА ОБОЗНАЧЕНИЯ

ВРУ – 1 – XX – YZ – УХЛ4.2 вводно-распределительное устройство
ВРУ – 1 – XX – YZ – УХЛ4.2 номер модели
ВРУ – 1 – XX – YZ – УХЛ4.2

назначение щита:

11-19 – вводные щиты

21-29 – вводно-распределительные щиты

41-50 – распределительные щиты

ВРУ – 1 – XX – YZ – УХЛ4.2

наличие вводного устройства

0 — без устройств ввода;
1 — устройство переключения 250А;
2 — устройство переключения 400А;
5 — рубильник на 250А;
6 — рубильник и предохранители на 250А;
7 — рубильник, предохранители и приборы автоматического ввода резерва на 100А;
8 — рубильник, предохранители и приборы автоматического ввода резерва на 250А.

ВРУ – 1 – XX – YZ – УХЛ4.2

дополнительные устройства

0 — отсутствует
1 — автоматический контроллер освещения с автоматами 30×16А
2 — ручной контроллер освещения с автоматами с автоматами 30×16А
3 -автоматический контроллер освещения с автоматами 14×16А
4 -ручной контроллер освещения с автоматами 14×16А
5 — автоматический контроллер освещения с автоматами 8×16А
6 -ручной контроллер освещения с автоматами 8×16А

ВРУ – 1 – XX – YZ – УХЛ4.2 требования по климатическому исполнению и категории размещения

 

ВВОДНЫЕ РУ

ТАБЛИЦА ТЕХНИЧЕСКИХ ХАРАКТЕРИСТИК

Принципиальная схема Тип ГОСТ, ТУ Номиналь-ный ток, А Кол-во и ток вводных аппаратов, А Кол-во и тип аппаратов вывода
Тип освещения Количество аппаратов учета ЭЭ
ВРУ1-21-10 УХЛ4.2 ТУ 3434-002-01395414-94

200

1х250 2х60 + 4х100 автоматическое 1
ВРУ1-22-55 УХЛ4.2 ТУ 3434-002-01395414-94 200 2х250 5х100 автоматическое 1
ВРУ1-23-55 УХЛ4.2 ТУ 3434-002-01395414-94 200 2х250 5х100 автоматическое 1
ВРУ1-24-55 УХЛ4.2 ТУ 3434-002-01395414-94 200 2х250 5х100 автоматическое 2
ВРУ1-25-65 УХЛ4.2 ТУ 3434-002-01395414-94 200 1х250 4х60 + 1х100 автоматическое 1
ВРУ1-26-65 УХЛ4.2 ТУ 3434-002-01395414-94 200 1х250 4х60 + 1х100 автоматическое 1
ВРУ1-27-65 УХЛ4.2 ТУ 3434-002-01395414-94 200 1х250 4х60 + 1х100 автоматическое 2
ВРУ1-28-65 УХЛ4.2 ТУ 3434-002-01395414-94 200 1х250 4х60 + 1х100 автоматическое 2
ВРУ1-29-65 УХЛ4.2 ТУ 3434-002-01395414-94 200 1х250 4х60 + 1х100 автоматическое 2
ВРУ1-22-54 УХЛ4.2 ТУ 3434-002-01395414-94 200 2х250 5х100 ручное 0
ВРУ1-23-54 УХЛ4.2 ТУ 3434-002-01395414-94 200 2х250 5х100 ручное
1

ВВОДНО-РАСПРЕДЕЛИТЕЛЬНЫЕ РУ

ТАБЛИЦА ТЕХНИЧЕСКИХ ХАРАКТЕРИСТИК

Принципиальная схема Тип ГОСТ, ТУ Номиналь-ный ток, А Кол-во и ток вводных аппаратов, А Тип освещения Количество аппаратов учета ЭЭ
ВРУ1-11-10 УХЛ4.2 ТУ 3434-002-01395414-94

250

2х250 автоматическое 2
ВРУ1-12-10 УХЛ4.2 ТУ 3434-002-01395414-94 250 2х250 автоматическое 2
ВРУ1-13-20 УХЛ4.2 ТУ 3434-002-01395414-94 400 2х400 автоматическое 2
ВРУ1-14-20 УХЛ4.2 ТУ 3434-002-01395414-94 400 2х400 автоматическое 2
ВРУ1-17-70 УХЛ4.2 ТУ 3434-002-01395414-94 100 1х100 автоматическое 1
ВРУ1-18-80 УХЛ4.2 ТУ 3434-002-01395414-94 250 1х250 автоматическое 1
ВРУ1-19-80 УХЛ4.2 ТУ 3434-002-01395414-94 250 2х250 автоматическое 1

СОБСТВЕННОЕ ПРОИЗВОДСТВО

Вводно-распределительное устройство — Большая Энциклопедия Нефти и Газа, статья, страница 3

Вводно-распределительное устройство

Cтраница 3

Вводно-распределительное устройство ШВУ-5 служит для приема, распределения и учета осветительных и силовых нагрузок в жилых домах и общественных зданиях, электроснабжение которых осуществляется от четырехпроводных электрических сетей напряжением 380 / 220 и 220 / 127 В с i лухочазем-ленной нейтралью.  [31]

Вводно-распределительные устройства жилых домов и потребителей с мелкомоторной нагрузкой ( кинотеатры, поликлиники, школы) обычно обслуживаются самим потребителем, а его конструкция в значительной степени зависит от схемы внутренней сети электроустановки этого потребителя.  [33]

Вводно-распределительные устройства ГЩВУ хозблоков и магазинов предназначаются для приема, распределения и учета эл. Шкафы являются типовой унифицированной конструкцией, позволяющей заполнять все необходимые схемы эл. Учет энергии вынесен в верхний блок шкафа с отдельной дверцей, закрывающейся замком. Корпус щита изготовляется из листогнутой стали и имеет лакокрасочное покрытие. Устанавливаются в любом удобном для обслуживания месте.  [34]

Инвентарные вводно-распределительные устройства ИВРУ-ЗБ на 3 отходящие линии и ИВРУ-6Б на 6 отходящих линий предназначены для приема, распределения и учета электрической энергии и защиты от перегрузок и токов к.  [35]

Вводно-распределительные устройства ВРУ-3 производства ЗАО ГТК ИЗНУ климатического исполнения УХЛ4 предназначены для установки в четырехпроводных и пятипроводных электрических сетях с системами заземления TN-C, TN-C-S, TN-S. ВРУ-3 обеспечивают защиту отходящих линий от перегрузок и коротких замыканий.  [37]

Вводно-распределительным устройством ( ВРУ) называется совокупность конструкций, аппаратов и приборов, устанавливаемых на вводе питающей линии в здание или в его обособленную часть, а также на отходящих от ВРУ линиях.  [38]

Рассмотрим вводно-распределительное устройство ВРУ-1 ( рис. 51) для приема, распределения и учета электрической энергии напряжением 380 / 220 В в сетях с глухозаземленной нейтралью трехфазного переменного тока частотой 50 Гц, а также для защиты линий при перегрузках и коротких замыканиях.  [39]

Выбор вводно-распределительного устройства с необходимой электрической схемой и электрическим оборудованием производят при проектировании электроснабжения жилого или общественного здания, питающегося от городских электрических сетей.  [40]

В вводно-распределительных устройствах ВРУ-70 ( рис. 2Ь), имеющих размеры 2000Х550Х ( 450 — 1100) мм, не предусмотрены верхнее и заднее закрытия. Панели устанавливают в электротехническом помещении прислонно к стене. При необходимости монтажа в производственном помещении их снабжают запирающейся передней дверью и Задней стенкой. Внутри конструкции монтируют коммутационную и защитную аппаратуру — рубильники, переключатели, предохранители, автоматы и трансформаторы тока. На внешней лицевой стороне располагают приборы измерений и учета. Рубильники и предохранители для большей безопасности обслуживающего персонала дополнительно ограждают асбоцементными перегородками. Сборные шины ВРУ-70 могут иметь сечение до 100 X10 мм и максимальный ток присоединения 600 А.  [42]

Чем отличается вводно-распределительное устройство от распределительного щита.  [43]

В шкафу вводно-распределительного устройства высокого напряжения ( рис. 29) расположены выключатель нагрузки 7 с предохранителем 5 и шины 4 и 6, к которым подсоединяют кабель и силовой трансформатор.  [44]

Страницы:      1    2    3    4    5

ВРУ 1Э и ВРУ 3Э Вводно- распределительные устройства

Вводно- распределительные устройства ВРУ 1Э и ВРУ 3Э

Вводно-распределительные устройства (ВРУ) 1Э используются для приема и передачи электрической энергии, а также они делают все устройства устойчивыми к перегрузкам и коротким замыканиям в сетях с переменным током 380/220 вольт и частотой 50 герц.
Отходящие и вводные шины, используемые в шкафах, изготовлены из алюминия. Шины, работающие в ВРУ 1Э без перебоев выдерживают токи коротких замыканий до 10 кА. Устройства автоуправления и ручного управления системами освещения находятся в отдельных отсеках.
Блоки автоуправления и ручного управления системами освещения в общественных местах и жилых зданиях монтируются в панели ВРУ 1Э на 8, 14 и 30 секций. Блоки дают возможность управления электроосвещением через фотореле (зависит от освещения) или через программное реле (зависит от времени). Вся аппараты для ведения учета и сбора информации (трансформаторы и счетчики) помещаются в отдельной секции.

Структура условного обозначения ВРУ-1Э

ВРУ могут быть вводными (ведение учета электроэнергии), распределительными (распределение энергии) и вводно-распределительные (применяются вместе с вводными ВРУ).

Габариты
L B Н
450 300 1600
600 300 1600
450 450 1800
600 450 1800
800 450 1800
450 450 2000
600 450 2000
800 450 2000
800 450 1700

Общий вид и габаритные размеры ВРУ-1Э и ВРУ-3Э

Вводно-распределительные устройства выполняются в напольном варианте со степенью защиты IP 30 и имеют габариты 1700 x 800 x 450. По согласованию с заказчиком вероятно изготовление нестандартных типов блоков.

 

Заказывая ВРУ 1Э, покупатель обязан представить для корректного монтажа следующую информацию:

  • Маркировка выбранного ВРУ 1
  • Место монтажа ВРУ 1 (в щитовой комнате или нет)  и область его применения
  • Номинальное напряжение тока ВРУ 1
  • Тип и номинальное напряжение защитных устройств
  • Сечение проводов питающей секции.

Вводно-распределительные устройства ВРУ-1Э и ВРУ-3Э

Вводно-распределительные устройства ВРУ-1Э и ВРУ-3Э используется для приема и передачи энергии, защиты аппаратуры от коротких замыканий и перегрузок в сетях с переменным током, использующим напряжение 380/220 Вольт, с частотой 50 и 60 Гц.
Вводно-распределительные устройства состоят из панелей с односторонним обслуживанием и выполняются в однопанельном и многопанельном вариантах. Панели для ВРУ-ЗЭ могут заменяться панелями от ВРУ-1Э, имеют меньший вес, размер и лучше скомпонованы.

Скачать и посмотреть схемы, документацию, техническую информацию, а так же опросный лист для формирования ТЗ можно здесь >>>>>

Технические характеристики

Вводно-распределительные устройства состоят из панелей с односторонним обслуживанием и выполняются в однопанельном и многопанельном вариантах. В панелях вмонтированы специальные аппараты, которые ведут постоянный учет энергии. Для управления в сетях общего пользования (к примеру, для управления освещением) применяются узлы и блоки автоматического и неавтоматического контроля за освещением. Командными аппаратами в этих ВРУ являются фотореле или фотореле вместе с реле времени.

назначение, виды, комплектация — Ремонт и Строительство

В электрике и энергетике расшифровка аббревиатуры ВРУ — вводно-распределительное устройство, иногда его еще называют УВР. Без этого элемента электрической цепи не обойтись в электроснабжении жилых домов и общественных зданий. На сегодняшний день ВРУ представляет собой закрытый ящик из стали, в котором находится большое количество аппаратов, используемых для контроля и учета электроэнергии, а также защиты подключаемых потребителей. В этой статье мы расскажем, для чего нужно вводно-распределительное устройство, из чего оно состоит и чем может быть укомплектовано

Назначение и область применения

Главным образом ВРУ служит для приема и последующего распределения электрической энергии. Помимо этого данный элемент предназначен для защиты подключаемых к нему потребителей от перегрузок, коротких замыканий, утечек тока и других аварийных ситуаций. Также следует отметить, что вводно-распределительные устройства применяют для учета израсходованной электроэнергии, а также контроля правильного распределения нагрузки по всей электрической сети. Ну и обязательно следует отметить, что с помощью распределительного устройства, установленного на вводе, могут производиться оперативные включения и отключения оборудования, которое подсоединено к этому участку цепи.

На фото ниже показано, как оно выглядит:

Если говорить вкратце, то основное назначение вводно-распределительного устройства заключается в объединении в одном месте контрольной и защитной аппаратуры, а также приборов, необходимых для измерения и учета электрической энергии. Благодаря этому на объекте можно компактно собрать все аппараты и управлять ими с одного места, защищенного от неблагоприятных погодных условий и других опасностей.

Как мы уже сказали выше, ВРУ применяется не только в административных зданиях и на промышленных предприятиях, но и в жилых домах (частных и многоквартирных). При составлении проекта электроснабжения указывается месторасположение вводно-распределительного устройства, а также характеристики всей аппаратуры, которая будет в нем установлена. Согласно проекту осуществляет сборка ВРУ и дальнейшая опломбировка прибора учета электроэнергии.

В частном доме ВРУ применяется в том случае, если возникает необходимость распределения нагрузки по нескольким постройкам (баня, хозблок, гараж, летняя кухня и т.д.). В таком случае устанавливается основной ВРУ, после которого необходимо установить индивидуальное распределительное устройство для каждой отдельной постройки.

Комплектация ВРУ

Устройства вводно-распределительные могут быть укомплектованы по разному, в зависимости от пожеланий заказчика и существующих требований. В основном, ВРУ в электрохозяйстве комплектуются защитной автоматикой, прибором учета электрической энергии, измерительной аппаратурой и шинами.

Если подробнее говорить о составляющих ВРУ, они следующие:

  1. Электросчетчик.
  2. Вводной автоматический выключатель и вводное УЗО.
  3. Групповые автоматические выключатели и УЗО (либо дифавтоматы).
  4. Шины (заземления, нулевые, токопроводящие).
  5. Провода и кабели, необходимые для коммутации всей аппаратуры.
  6. Наборные клеммники для коммутации цепей.

Помимо этого, в зависимости от области применения вводно-распределительных устройств, они могут быть оснащены трансформаторами тока, кварцевыми предохранителями, ограничителями напряжения, вольтметрами, амперметрами, разрядниками, средствами защиты и прочими аппаратами. Как уже было сказано, комплектация ВРУ зависит от проекта электроснабжения и индивидуальных предпочтений заказчика.

Виды вводно-распределительных устройств

Последнее, о чем хотелось бы рассказать в этой статье — какие бывают виды ВРУ. Итак, условно мы разделили их на следующие разновидности:

  1. По номинальному току: 100, 250, 400, 630 А.
  2. По типу исполнения: подвесной, напольный.
  3. По назначению: вводные, распределительные, вводно-распределительные.
  4. По месту установки: в помещениях и уличные. Тут важно указать, что степень защиты может быть от IP31 до IP65.
  5. По типу обслуживания: односторонние, двухсторонние.
  6. По количеству вводов: на 1 ввод или на несколько (2, 3, 4).

Важно отметить, что сами распределительные устройства могут быть одно-, двух-, трехпанельными и более (многопанельные). Размеры ящика также зависят от его комплектации и области применения.

Маркировка ВРУ дает понять, какими характеристиками обладает данное устройство. Аббревиатура расшифровывается следующим образом:

Напоследок рекомендуем просмотреть видео, на которых более подробно рассказывается о том, как устроены УВР:

На этом мы и заканчиваем нашу статью. Надеемся, теперь вам стало понятно, для чего служит вводно-распределительное устройство и какие варианты исполнения существуют. Надеемся, предоставленная информация была для вас полезной и интересной!

Вводно-распределительные устройства ВРУ-8504, 8505

 

      ВРУ-8504, ВРУ-8505 предназначены для приема, распределения и учета электрической энергии напряжением 380/220В трехфазного переменного тока частотой 50 Гц в сетях с глухозаземленной нейтралью, для защиты линий при перегрузках и коротких замыканиях, а также для нечастых (до 6 включений в час) оперативных включений и отключений электрических сетей. 

Номенклатура ВРУ-8504, ВРУ-8505 разработана на базе автоматических выключателей серии ВА88, и ВА47-63, УЗО, пускателей серии КМИ, предохранителей ППН, пакетных выключателей серии ПВ, выключателей и переключателей ВР32 отечественного производства.

Так же по согласованию с заказчиком аппаратура может быть заменена на аппаратуру фирм ABB, Schneider Electric, Legrand без изменения типа изделия и конструкции шкафов.

Конструкция панелей ввода позволяет устанавливать измерительные приборы (амперметры, вольтметр). При этом добавляется еще ряд трансформаторов тока и переключатель вольтметровый.

По назначению панели ВРУ изготавливаются следующих видов:

 

— вводные с выключателем врубным,

— вводные с переключателем врубным,

— вводные с выключателем автоматическим,

— распределительные с выключателями автоматическими на отходящих линиях,

— распределительные с автоматикой управления освещением лестнично-лифтового узла и коридоров,

— распределительные с отделением учета.

Вводные панели ВРУ имеют отделение учета, в котором устанавливаются:

 

— трансформаторы тока типа ТТН, ТТИ или аналогичные;

— счетчик трехфазный электронный;

— коробка испытательная переходная;

— лампочка подсвета;

Принятая схема условных обозначений расшифровывается следующим образом:

ВРУ – вводно – распределительное устройство;

8 – устройство ввода и распределения электрической энергии;

5 – распределение электрической энергии с применением автоматических выключателей;

05 – пятый выпуск разработки.

В состав вводно-распределительного устройства ВРУ-8505 включены станции управления (панели АВР) для автоматического переключения на резерв освещения и силового электрооборудования при исчезновении напряжения нормального питания и предназначены для применения в сетях переменного тока с фазным напряжением до 220В.

 

 

 

 

(PDF) Методика расчета вводно-распределительных устройств

характеристика С 0,4 кВ устанавливаются в качестве вводных устройств для защиты

сети. Машины категории B выбраны для защиты

линий отходов грузов.

2 Методика выбора и расчета

устройств защитного

отключения

В зависимости от мощности подключаемого оборудования,

наличия промежуточных защитных устройств и длины

электропроводки, дифференциального тока используется устройство (УЗО) с

различными ограничениями дифференциального тока.

Наиболее распространенными устройствами защиты являются 10 мА, 30

мА и 100 мА. Этих устройств достаточно для защиты

большинства жилых и офисных помещений.

Выбор устройства защитного отключения

производится по следующим параметрам:

1) Рабочее напряжение: 220В или 380В, комбинированные

варианты доступны;

2) Род тока: При переменном токе утечки

ТП должен отключаться, при типе

А ТП должен отключаться при постоянном и

переменном токе утечки;

3) Количество полюсов: биполярный или четырехполюсный;

4) Энергетическая зависимость.Возможность отключения питания без рабочего напряжения

;

5) Конструктивное исполнение: установка осуществляется на DIN-стойку

, крепление в виде розетки, которая

переносная и крепится к стене;

6) Тип реле: электромеханическое и электронное.

Первые должны размыкаться механически,

другие — с помощью полупроводниковой схемы;

7) Рабочая скорость: мгновенная и селективная;

8) Дополнительные функции: например, УЗО с

КЗ или УЗО без защиты от перегрузки сети.

Устройство защитного отключения срабатывает при определенном

уровне дифференциального тока, возникающего между жилами

электрического кабеля. Следующая формула используется для

Рассчитать дифференциальный ток RCD

0, 4 0, 01

1000

1000

IL

IL

IL

I

(MA) (1)

, где ICALC — расчетный ток на данном

участке цепи, А; LWIRE – расчетная длина

провода, м.

Следует учитывать, что порог

ток аппарата должен быть в 3 раза выше:

IПОРОГ=3I- (2)

3 Способ выбора дифференциального тока

автоматы

Автоматический выключатель дифференциального тока объединяет функции

двух устройств защиты автоматического выключателя

и защитного выключателя.

Рассчитайте номинальный ток дифференциального автомата

так же, как и для автоматических выключателей.

По стандартным номиналам диффузоров

выбрать подходящий. Следующим этапом является проверка

тока утечки по формуле (2) и проверка

времятоковой характеристики выключателя.

4 Способ выбора электросчетчика

При выборе счетчика электроэнергии необходимо

учитывать фазу электросети, будь то

однофазная или трехфазная.Электросчетчик должен быть

установлен после вводного выключателя, так как счетчик должен быть

защищен от тока короткого замыкания.

Счетчик подбирается исходя из параметров

указанных в паспорте.

Из имеющихся на данный момент электронных и индукционных счетчиков

выбираем электронный по заявке энергоснабжающей организации

. Текущий выбор

основан на базовом и максимальном значениях.Базовые значения 5

и 10 А, самые популярные 60 и 100 А для

максимального тока. Если ток превышает максимальные значения тока

, то для подключения тока следует использовать измерительные трансформаторы тока

.

Счетчик может регистрировать как активную энергию, так и реактивную

энергию. В паспорте счетчика классы точности

представлены в виде дробей: первое значение соответствует

классу точности по активной энергии, второе значение

соответствует классу точности по реактивной энергии.

Счетчики делятся по количеству тарифов. Есть

однотарифные и многотарифные. Параметры

выбираются по желанию заказчика и согласовываются с

поставщиком энергоуслуг.

5 Метод выбора измерительных

трансформаторов тока

Электроэнергию с током питания более

100 А учитывают при подключении измерительных

трансформаторов. Для выбора трансформатора тока необходимо

знать значение максимального тока

, протекающего в питающей сети.Номинальный ток

первичной обмотки трансформатора определяет коэффициент трансформации

.

Коэффициент трансформации

следует выбирать по расчетной нагрузке с учетом

аварийного режима. Трансформаторы тока с завышенным коэффициентом трансформации

(электродинамическое и

термическое сопротивление или защита шин) допускаются

по ПУЭ, если при максимальной нагрузке присоединения

ток во вторичной обмотке

тока трансформатора не менее 40 % от номинального

тока счетчика, а при минимальной рабочей нагрузке

не менее 5 %.

Класс точности также важен при выборе трансформаторов тока

. Для рассматриваемых условий

4 класса точности: 0,5; 0,5 с; 1; 2.

6 Метод выбора жилы

сечения

Сечение жилы выбирают по

исходя из следующих параметров:

1) Расчетная суммарная мощность приемников, кВт;

2) Расчетный рабочий ток группы приемников

, А;

E3S Web of Conferences 216, 01085 (2020)

RSES 2020

https://doi.org/10.1051/e3sconf/202021601085

2

Распределенный ввод  | Ядро TensorFlow

API-интерфейсы tf.distribute предоставляют пользователям простой способ масштабировать свое обучение с одного компьютера на несколько компьютеров. При масштабировании своей модели пользователям также приходится распределять вводимые данные на несколько устройств. tf.distribute предоставляет API, с помощью которых вы можете автоматически распределять вводимые данные между устройствами.

Это руководство покажет вам различные способы создания распределенного набора данных и итераторов с помощью tf.распространять API . Дополнительно будут затронуты следующие темы:

В этом руководстве не рассматривается использование распределенного ввода с API-интерфейсами Keras.

Распределенные наборы данных

Чтобы использовать API tf.distribute для масштабирования, используйте tf.data.Dataset для представления их входных данных. tf.distribute эффективно работает с tf.data.Dataset — например, за счет автоматической предварительной загрузки на каждое ускорительное устройство и регулярных обновлений производительности.Если у вас есть прецедент для использования чего-то другого, кроме tf.data.Dataset , обратитесь к разделу Tensor inputs в этом руководстве. В нераспределенном обучающем цикле сначала создайте экземпляр tf.data.Dataset , а затем выполните итерацию по элементам. Например:

  импортировать тензорный поток как tf

# Вспомогательные библиотеки
импортировать numpy как np
импорт ОС

печать (tf.__версия__)
  
2.8.0
 
  # Имитация нескольких процессоров с виртуальными устройствами
N_ВИРТУАЛЬНЫХ_УСТРОЙСТВ = 2
физические_устройства = tf.config.list_physical_devices("ЦП")
tf.config.set_logical_device_configuration(
    Physical_devices[0], [tf.config.LogicalDeviceConfiguration() для _ в диапазоне (N_VIRTUAL_DEVICES)])
  
  print("Доступные устройства:")
для i устройство в перечислении (tf.config.list_logical_devices()):
  print("%d) %s" % (я, устройство))
  
Доступные устройства&двоеточие;

0) LogicalDevice(name='/device:CPU:0', device_type='CPU')
1) LogicalDevice(name='/device:CPU:1', device_type='CPU')
2) LogicalDevice(name='/device:GPU:0', device_type='GPU')
 
  global_batch_size = 16
# Создать тф.объект data.Dataset.
набор данных = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(global_batch_size)

@tf.function
def train_step (входы):
  функции, метки = входы
  обратные метки - 0,3 * характеристики

# Перебираем набор данных, используя конструкцию for..in.
для входных данных в наборе данных:
  печать (train_step (входы))
  
tf.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
tf.Тензор(
[[0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
tf.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
tf.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
tf.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
tf.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
tf.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(4, 1), dtype=float32)
 

Чтобы позволить пользователям использовать стратегию tf.distribute с минимальными изменениями в существующем коде пользователя, были введены два API, которые будут распространять tf.data.Dataset и вернуть объект распределенного набора данных. Затем пользователь может выполнить итерацию по этому экземпляру распределенного набора данных и обучить свою модель, как и раньше. Давайте теперь рассмотрим два API — tf.distribute.Strategy.experimental_distribute_dataset и tf.distribute.Strategy.distribute_datasets_from_function более подробно:

tf.distribute.Strategy.experimental_distribute_dataset
Применение

Этот API принимает tf.экземпляр data.Dataset в качестве входных данных и возвращает экземпляр tf.distribute.DistributedDataset . Вы должны пакетировать входной набор данных со значением, равным глобальному размеру пакета. Этот глобальный размер пакета — это количество образцов, которые вы хотите обработать на всех устройствах за 1 шаг. Вы можете выполнить итерацию по этому распределенному набору данных в стиле Python или создать итератор, используя iter . Возвращенный объект не является экземпляром tf.data.Dataset и не поддерживает какие-либо другие API-интерфейсы, которые каким-либо образом преобразуют или проверяют набор данных.Это рекомендуемый API, если у вас нет конкретных способов разделения входных данных на разные реплики.

  global_batch_size = 16
mirrored_strategy = tf.distribute.MirroredStrategy()

набор данных = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(global_batch_size)
# Распространяйте входные данные, используя `experimental_distribute_dataset`.
dist_dataset = зеркальная_стратегия.experimental_distribute_dataset(набор данных)
# 1 глобальный пакет данных, передаваемых в модель за 1 шаг.печать (следующая (iter (dist_dataset)))
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
(, )
2022-03-26 01:22:18.089999: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:776] Политика сегментации AUTO будет применять политику сегментации DATA, поскольку не удалось применить политику сегментации FILE по следующей причине: Найден нерасчленяемый исходный набор данных: имя&двоеточие; "TensorDataset/_2"
оп&колон; «ТензорДатасет»
ввод&двоеточие; "Заполнитель/_0"
ввод&двоеточие; "Заполнитель/_1"
атрибут {
  ключ&двоеточие; "Toutput_types"
  ценность {
    список {
      тип&двоеточие; DT_FLOAT
      тип&двоеточие; DT_FLOAT
    }
  }
}
атрибут {
  ключ&двоеточие; "_кардинальность"
  ценность {
    я&двоеточие; 1
  }
}
атрибут {
  ключ&двоеточие; "метаданные"
  ценность {
    с&двоеточие; "\n\017TensorDataset:4"
  }
}
атрибут {
  ключ&двоеточие; "output_shapes"
  ценность {
    список {
      форма {
        тусклый {
          размер&двоеточие; 1
        }
      }
      форма {
        тусклый {
          размер&двоеточие; 1
        }
      }
    }
  }
}
экспериментальный_тип {
  type_id: TFT_PRODUCT
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
}
 
Свойства
Пакетирование

тс.Distribute выполняет повторное пакетирование входного экземпляра tf.data.Dataset с новым размером пакета, равным общему размеру пакета, деленному на количество синхронизированных реплик. Количество синхронизированных реплик равно количеству устройств, которые принимают участие в градиенте allreduce во время обучения. Когда пользователь вызывает next на распределенном итераторе, для каждой реплики возвращается размер пакета данных для каждой реплики. Количество элементов в повторно пакетированном наборе данных всегда будет кратно количеству реплик.Вот несколько примеры:

  • tf.data.Dataset.range(6).batch(4, drop_remainder=False)

  • tf.data.Dataset.range(4).batch(4)

    • Без распределения:
    • Пакет 1: [0, 1, 2, 3]
    • При распределении по 5 репликам:
    • Пакет 1:
      • Реплика 1: [0]
      • Реплика 2: [1]
      • Реплика 3: [2]
      • Реплика 4: [3]
      • Реплика 5: []
  • тс.data.Dataset.range(8).batch(4)

    • Без распределения:
    • Пакет 1: [0, 1, 2, 3]
    • Пакет 2: [4, 5, 6, 7]
    • С распространением на 3 реплики:
    • Пакет 1:
      • Реплика 1: [0, 1]
      • Реплика 2: [2, 3]
      • Реплика 3: []
    • Пакет 2:
      • Реплика 1: [4, 5]
      • Реплика 2: [6, 7]
      • Реплика 3: []
Примечание: Приведенные выше примеры только иллюстрируют, как глобальный пакет разбивается на разные реплики.Не рекомендуется полагаться на фактические значения, которые могут оказаться в каждой реплике, поскольку они могут меняться в зависимости от реализации.

Повторная пакетная обработка набора данных имеет пространственную сложность, линейно увеличивающуюся с количеством реплик. Это означает, что в случае обучения с несколькими работниками входной конвейер может столкнуться с ошибками OOM.

Шардинг

tf.distribute также автоматически разбивает входной набор данных при обучении нескольких сотрудников с помощью MultiWorkerMirroredStrategy и TPUDStrategy .Каждый набор данных создается на процессорном устройстве рабочего. Автошардинг набора данных по набору воркеров означает, что каждому воркеру назначается подмножество всего набора данных (если установлено право tf.data.experimental.AutoShardPolicy ). Это делается для того, чтобы на каждом этапе глобальный размер пакета непересекающихся элементов набора данных обрабатывался каждым работником. Autosharding имеет несколько различных параметров, которые можно указать с помощью tf.data.experimental.DistributeOptions . Обратите внимание, что в обучении нескольких сотрудников с помощью ParameterServerStrategy нет автоматического сегментирования, и дополнительную информацию о создании набора данных с помощью этой стратегии можно найти в руководстве по ParameterServerStrategy.

  набор данных = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(64).batch(16)
опции = tf.data.Options()
options.experimental_distribute.auto_shard_policy = tf.data.experimental.AutoShardPolicy.DATA
набор данных = набор данных.with_options (параметры)
  

Существует три разных параметра, которые можно установить для tf.data.experimental.AutoShardPolicy :

.
  • АВТОМАТИЧЕСКИ: это параметр по умолчанию, который означает, что будет предпринята попытка сегментировать ФАЙЛ. Попытка разбиения по ФАЙЛУ завершается неудачно, если набор данных на основе файлов не обнаружен. tf.distribute затем вернется к сегментированию по ДАННЫМ. Обратите внимание, что если входной набор данных основан на файлах, но количество файлов меньше количества рабочих процессов, будет выдано сообщение об ошибке InvalidArgumentError . В этом случае явно задайте для политики значение AutoShardPolicy.DATA или разделите источник ввода на файлы меньшего размера, чтобы количество файлов превышало количество рабочих процессов.
  • ФАЙЛ: Это вариант, если вы хотите разбить входные файлы на всех рабочих.Вы должны использовать эту опцию, если количество входных файлов намного больше, чем количество рабочих процессов, и данные в файлах распределены равномерно. Недостатком этого варианта является наличие простаивающих рабочих, если данные в файлах распределены неравномерно. Если количество файлов меньше количества рабочих процессов, будет выдано сообщение об ошибке InvalidArgumentError . В этом случае явно задайте для политики значение AutoShardPolicy.DATA . Например, давайте распределим 2 файла по 2 воркерам с 1 репликой каждый.Файл 1 содержит [0, 1, 2, 3, 4, 5] и Файл 2 содержит [6, 7, 8, 9, 10, 11]. Пусть общее количество синхронизированных реплик равно 2, а размер глобального пакета равен 4.

    • Рабочий 0:
    • Пакет 1 = Реплика 1: [0, 1]
    • Пакет 2 = Реплика 1: [2, 3]
    • Пакет 3 = Реплика 1: [4]
    • Пакет 4 = Реплика 1: [5]
    • Рабочий 1:
    • Пакет 1 = Реплика 2: [6, 7]
    • Пакет 2 = Реплика 2: [8, 9]
    • Пакет 3 = Реплика 2: [10]
    • Пакет 4 = Реплика 2: [11]
  • ДАННЫЕ: это приведет к автоматическому разбиению элементов по всем рабочим процессам.Каждый из рабочих будет читать весь набор данных и обрабатывать только назначенный ему сегмент. Все остальные осколки будут удалены. Это обычно используется, если количество входных файлов меньше, чем количество рабочих процессов, и вы хотите лучше разделить данные по всем рабочим процессам. Недостатком является то, что весь набор данных будет прочитан на каждом воркере. Например, давайте распределим 1 файл по 2 рабочим. Файл 1 содержит [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]. Пусть общее количество синхронизированных реплик равно 2.

    • Рабочий 0:
    • Пакет 1 = Реплика 1: [0, 1]
    • Пакет 2 = Реплика 1: [4, 5]
    • Пакет 3 = Реплика 1: [8, 9]
    • Рабочий 1:
    • Пакет 1 = Реплика 2: [2, 3]
    • Пакет 2 = Реплика 2: [6, 7]
    • Пакет 3 = Реплика 2: [10, 11]
  • OFF: Если вы отключите автошардинг, каждый воркер будет обрабатывать все данные.Например, давайте распределим 1 файл по 2 рабочим. Файл 1 содержит [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]. Пусть общее количество реплик в синхронизации равно 2. Тогда каждый воркер увидит следующее распределение:

    • Рабочий 0:
    • Пакет 1 = Реплика 1: [0, 1]
    • Пакет 2 = Реплика 1: [2, 3]
    • Пакет 3 = Реплика 1: [4, 5]
    • Пакет 4 = Реплика 1: [6, 7]
    • Пакет 5 = Реплика 1: [8, 9]
    • Пакет 6 = Реплика 1: [10, 11]

    • Рабочий 1:

    • Пакет 1 = Реплика 2: [0, 1]

    • Пакет 2 = Реплика 2: [2, 3]

    • Пакет 3 = Реплика 2: [4, 5]

    • Пакет 4 = Реплика 2: [6, 7]

    • Пакет 5 = Реплика 2: [8, 9]

    • Пакет 6 = Реплика 2: [10, 11]

Предварительная выборка

По умолчанию тс.Распространение добавляет преобразование предварительной выборки в конце предоставленного пользователем экземпляра tf.data.Dataset . Аргумент преобразования предварительной выборки, который равен размеру буфера , равен количеству синхронизированных реплик.

tf.distribute.Strategy.distribute_datasets_from_function
Применение

Этот API принимает функцию ввода и возвращает экземпляр tf.distribute.DistributedDataset . Функция ввода, которую передают пользователи, имеет значение tf.распределите.InputContext и должен вернуть экземпляр tf.data.Dataset . С помощью этого API tf.distribute не вносит никаких дальнейших изменений в пользовательский экземпляр tf.data.Dataset , возвращенный функцией ввода. Ответственность за пакетную обработку и сегментацию набора данных лежит на пользователе. tf.distribute вызывает функцию ввода на процессорном устройстве каждого из воркеров. Помимо предоставления пользователям возможности указывать собственную логику пакетной обработки и сегментирования, этот API также демонстрирует лучшую масштабируемость и производительность по сравнению с tf.Distribute.Strategy.experimental_distribute_dataset при использовании для обучения нескольких сотрудников.

  mirrored_strategy = tf.distribute.MirroredStrategy()

определение набора данных_fn (входной_контекст):
  batch_size = input_context.get_per_replica_batch_size (global_batch_size)
  набор данных = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(64).batch(16)
  набор данных = набор данных.осколок(
      input_context.num_input_pipelines, input_context.input_pipeline_id)
  набор данных = набор данных.пакет (размер_пакета)
  набор данных = набор данных.prefetch(2) # Выполняет предварительную выборку 2 пакетов на устройство.
  вернуть набор данных

dist_dataset = зеркальная_стратегия.distribute_datasets_from_function(dataset_fn)
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
 
Свойства
Пакетирование

Экземпляр tf.data.Dataset , который является возвращаемым значением функции ввода, должен быть упакован с использованием размера пакета для каждой реплики.Размер пакета реплики — это глобальный размер пакета, разделенный на количество реплик, участвующих в обучении синхронизации. Это связано с тем, что tf.distribute вызывает функцию ввода на процессорном устройстве каждого из воркеров. Набор данных, созданный для данного рабочего процесса, должен быть готов к использованию всеми репликами этого рабочего процесса.

Шардинг

Объект tf.distribute.InputContext , который неявно передается в качестве аргумента пользовательской функции ввода, создается tf.раздать под капот. Он содержит информацию о количестве рабочих, текущем идентификаторе рабочего и т. д. Эта функция ввода может обрабатывать сегментирование в соответствии с политиками, установленными пользователем, с использованием этих свойств, которые являются частью объекта tf.distribute.InputContext .

Предварительная выборка

tf.distribute не добавляет преобразование предварительной выборки в конце tf.data.Dataset , возвращаемого предоставленной пользователем функцией ввода, поэтому вы явно вызываете Dataset.prefetch в приведенном выше примере.

Примечание: И tf.distribute.Strategy.experimental_distribute_dataset , и tf.distribute.Strategy.distribute_datasets_from_function возвращают tf.distribute.DistributedDataset экземпляров, которые не относятся к типу tf.data.Dataset 9.4230 tf.data.Dataset . Вы можете перебирать эти экземпляры (как показано в разделе «Распределенные итераторы») и использовать element_spec . свойство.

Распределенные итераторы

Аналогичен нераспространяемому тс.data.Dataset , вам потребуется создать итератор для экземпляров tf.distribute.DistributedDataset , чтобы выполнить итерацию по нему и получить доступ к элементам tf.distribute.DistributedDataset . Ниже приведены способы создания tf.distribute.DistributedIterator и использования его для обучения модели:

Использование

Используйте конструкцию цикла Pythonic for

Вы можете использовать удобный цикл Pythonic для перебора tf.распределить.DistributedDataset . Элементы, возвращаемые из tf.distribute.DistributedIterator , могут быть одним tf.Tensor или tf.distribute.DistributedValues ​​, который содержит значение для каждой реплики. Размещение цикла внутри tf.function даст прирост производительности. Однако break и return в настоящее время не поддерживаются для цикла по tf.distribute.DistributedDataset , который помещен внутри tf.функция .

  global_batch_size = 16
mirrored_strategy = tf.distribute.MirroredStrategy()

набор данных = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(global_batch_size)
dist_dataset = зеркальная_стратегия.experimental_distribute_dataset(набор данных)

@tf.function
def train_step (входы):
  функции, метки = входы
  обратные метки - 0,3 * характеристики

для x в dist_dataset:
  # train_step обучает модель, используя элементы набора данных
  потеря = mirrored_strategy.run (train_step, args = (x,))
  print("Убыток ", убыток)
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
2022-03-26 01:22:18.189481: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:776] Политика сегментации AUTO будет применять политику сегментации DATA, поскольку не удалось применить политику сегментации FILE по следующей причине: Найден нерасчленяемый исходный набор данных: имя&двоеточие; "TensorDataset/_2"
оп&колон; «ТензорДатасет»
ввод&двоеточие; "Заполнитель/_0"
ввод&двоеточие; "Заполнитель/_1"
атрибут {
  ключ&двоеточие; "Toutput_types"
  ценность {
    список {
      тип&двоеточие; DT_FLOAT
      тип&двоеточие; DT_FLOAT
    }
  }
}
атрибут {
  ключ&двоеточие; "_кардинальность"
  ценность {
    я&двоеточие; 1
  }
}
атрибут {
  ключ&двоеточие; "метаданные"
  ценность {
    с&двоеточие; "\n\020TensorDataset:29"
  }
}
атрибут {
  ключ&двоеточие; "output_shapes"
  ценность {
    список {
      форма {
        тусклый {
          размер&двоеточие; 1
        }
      }
      форма {
        тусклый {
          размер&двоеточие; 1
        }
      }
    }
  }
}
экспериментальный_тип {
  type_id: TFT_PRODUCT
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
}
Убыток тс.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0.7]
 [0.7]], форма=(4, 1), dtype=float32)
 
Используйте
iter для создания явного итератора

Чтобы перебирать элементы в экземпляре tf.distribute.DistributedDataset , вы можете создать tf.distribute.DistributedIterator , используя API iter . С явным итератором вы можете выполнять итерацию фиксированное количество шагов. Чтобы получить следующий элемент из экземпляра tf.distribute.DistributedIterator dist_iterator , вы можете вызвать next(dist_iterator) , dist_iterator.get_next() или dist_iterator.get_next_as_Optional() . Первые два по существу одинаковы:

  число_эпох = 10
шагов_за_эпоху = 5
для эпохи в диапазоне (num_epochs):
  dist_iterator = iter (dist_dataset)
  для шага в диапазоне (steps_per_epoch):
    # train_step обучает модель, используя элементы набора данных
    потеря = mirrored_strategy.run (train_step, args = (следующий (dist_iterator)),))
    # что то же самое, что и
    # loss = mirrored_strategy.run(train_step, args=(dist_iterator.получить_следующий(),))
    print("Убыток ", убыток)
  
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Убыток тс.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Убыток тс.Тензор(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
Потеря tf.Tensor(
[[0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0,7]
 [0.7]], форма=(16, 1), dtype=float32)
 

С next или tf.distribute.DistributedIterator.get_next , если tf.distribute.DistributedIterator достиг своего конца, будет выдана ошибка OutOfRange. Клиент может перехватить ошибку на стороне Python и продолжить выполнение другой работы, такой как контрольные точки и оценка. Однако это не сработает, если вы используете цикл обучения хоста (т. е. выполняете несколько шагов на tf.функция ), которая выглядит так:

  @tf.функция
def train_fn (итератор):
  для _ в tf.range (steps_per_loop):
    Strategy.run (step_fn, args = (следующий (итератор)),))
  

Этот пример train_fn содержит несколько шагов, тело шага заключено в tf.range . В этом случае разные итерации в цикле без зависимости могут запускаться параллельно, поэтому ошибка OutOfRange может быть вызвана в более поздних итерациях до завершения вычисления предыдущих итераций.Как только выдается ошибка OutOfRange, все операции в функции будут немедленно завершены. Если вы хотите избежать этого, альтернативой, которая не выдает ошибку OutOfRange, является tf.distribute.DistributedIterator.get_next_as_Optional . get_next_as_Optional возвращает tf.experimental.Optional , который содержит следующий элемент или не содержит значения, если tf.distribute.DistributedIterator достиг конца.

  # Вы можете прервать цикл с помощью `get_next_as_Optional`, проверив, содержит ли `Optional` значение
global_batch_size = 4
шагов_за_цикл = 5
стратегия = тс.распределить.MirroredStrategy()

набор данных = tf.data.Dataset.range(9).batch(global_batch_size)
распределенный_итератор = итератор (strategy.experimental_distribute_dataset (набор данных))

@tf.function
def train_fn (распределенный_итератор):
  для _ в tf.range (steps_per_loop):
    необязательные_данные = распределенный_итератор.get_next_as_Optional()
    если не option_data.has_value():
      перемена
    per_replica_results = Strategy.run(лямбда х: х, аргументы=(необязательные_данные.get_value(),))
    tf.print (стратегия.experimental_local_results (per_replica_results))
train_fn (распределенный_итератор)
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
2022-03-26 01:22:19.146625: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:776] Политика сегментации AUTO будет применять политику сегментации DATA, поскольку не удалось применить политику сегментации FILE по следующей причине: Найден нерасчленяемый исходный набор данных: имя&двоеточие; "Диапазондатасет/_3"
оп&колон; "RangeDataset"
ввод&двоеточие; "Пост/_0"
ввод&двоеточие; "Пост/_1"
ввод&двоеточие; "Пост/_2"
атрибут {
  ключ&двоеточие; "_кардинальность"
  ценность {
    я&двоеточие; 9
  }
}
атрибут {
  ключ&двоеточие; "метаданные"
  ценность {
    с&двоеточие; "\n\020RangeDataset:104"
  }
}
атрибут {
  ключ&двоеточие; "output_shapes"
  ценность {
    список {
      форма {
      }
    }
  }
}
атрибут {
  ключ&двоеточие; "выходные_типы"
  ценность {
    список {
      тип&двоеточие; DT_INT64
    }
  }
}
экспериментальный_тип {
  type_id: TFT_PRODUCT
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_INT64
        }
      }
    }
  }
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_INT64
        }
      }
    }
  }
}
([0 1 2 3])
([4 5 6 7],)
([8])
 

Использование свойства

element_spec

Если вы передаете элементы распределенного набора данных в tf.function и хотите получить гарантию tf.TypeSpec , вы можете указать аргумент input_signature tf.function . Выходные данные распределенного набора данных — tf.distribute.DistributedValues ​​, которые могут представлять входные данные для одного или нескольких устройств. Чтобы получить tf.TypeSpec , соответствующий этому распределенному значению, вы можете использовать tf.distribute.DistributedDataset.element_spec или tf.distribute.DistributedIterator.element_spec .

  global_batch_size = 16
эпох = 5
шагов_за_эпоху = 5
mirrored_strategy = tf.distribute.MirroredStrategy()

набор данных = tf.data.Dataset.from_tensors(([1.], [1.])).repeat(100).batch(global_batch_size)
dist_dataset = зеркальная_стратегия.experimental_distribute_dataset(набор данных)

@tf.function(input_signature=[dist_dataset.element_spec])
def train_step (per_replica_inputs):
  def step_fn (входы):
    вернуть 2 * входы

  return mirrored_strategy.run (step_fn, args = (per_replica_inputs,))

для _ в диапазоне (эпохи):
  итератор = итератор (dist_dataset)
  для _ в диапазоне (steps_per_epoch):
    вывод = train_step (следующий (итератор))
    тф.печать (вывод)
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
2022-03-26 01:22:20.426675: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:776] Политика сегментации AUTO будет применять политику сегментации DATA, поскольку не удалось применить политику сегментации FILE по следующей причине: Найден нерасчленяемый исходный набор данных: имя&двоеточие; "TensorDataset/_2"
оп&колон; «ТензорДатасет»
ввод&двоеточие; "Заполнитель/_0"
ввод&двоеточие; "Заполнитель/_1"
атрибут {
  ключ&двоеточие; "Toutput_types"
  ценность {
    список {
      тип&двоеточие; DT_FLOAT
      тип&двоеточие; DT_FLOAT
    }
  }
}
атрибут {
  ключ&двоеточие; "_кардинальность"
  ценность {
    я&двоеточие; 1
  }
}
атрибут {
  ключ&двоеточие; "метаданные"
  ценность {
    с&двоеточие; "\n\021TensorDataset:118"
  }
}
атрибут {
  ключ&двоеточие; "output_shapes"
  ценность {
    список {
      форма {
        тусклый {
          размер&двоеточие; 1
        }
      }
      форма {
        тусклый {
          размер&двоеточие; 1
        }
      }
    }
  }
}
экспериментальный_тип {
  type_id: TFT_PRODUCT
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
}
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
([[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]], [[1]
 [1]
 [1]
 ...
 [1]
 [1]
 [1]])
 

Предварительная обработка данных

Итак, вы научились распространять tf.data.Dataset . Тем не менее, прежде чем данные будут готовы для модели, их необходимо предварительно обработать, например, путем очистки, преобразования и дополнения. Два набора этих удобных инструментов:

  • Уровни предварительной обработки Keras: набор слоев Keras, которые позволяют разработчикам создавать собственные конвейеры обработки ввода Keras. Некоторые слои предварительной обработки Keras содержат необучаемые состояния, которые можно установить при инициализации или адаптации ed (см. раздел адаптации руководства по слоям предварительной обработки Keras).При распределении слоев предварительной обработки с отслеживанием состояния состояния должны быть реплицированы на все рабочие процессы. Чтобы использовать эти слои, вы можете либо сделать их частью модели, либо применить к наборам данных.

  • TensorFlow Transform (tf.Transform): библиотека для TensorFlow, которая позволяет определять как преобразование данных на уровне экземпляра, так и полное преобразование данных с помощью конвейеров предварительной обработки данных. Tensorflow Transform состоит из двух фаз. Первый — это этап анализа, на котором необработанные обучающие данные анализируются в процессе полного прохода для вычисления статистики, необходимой для преобразований, а логика преобразования генерируется как операции на уровне экземпляра.Второй — этап преобразования, на котором необработанные обучающие данные преобразуются в процессе уровня экземпляра.

Слои предварительной обработки Keras и Tensorflow Transform

Уровни предварительной обработки Tensorflow Transform и Keras позволяют разделить предварительную обработку во время обучения и связать предварительную обработку с моделью во время логического вывода, уменьшая перекос между обучением и обслуживанием.

Tensorflow Transform, глубоко интегрированный с TFX, предоставляет масштабируемое решение для уменьшения карты для анализа и преобразования наборов данных любого размера в задании, отдельном от конвейера обучения.Если вам нужно выполнить анализ набора данных, который не помещается на одной машине, Tensorflow Transform должен быть вашим первым выбором.

Слои предварительной обработки Keras больше ориентированы на предварительную обработку, применяемую во время обучения после чтения данных с диска. Они идеально подходят для разработки моделей в библиотеке Keras. Они поддерживают анализ меньшего набора данных с помощью адаптации и поддерживают варианты использования, такие как увеличение данных изображения, где каждый проход по входному набору данных дает разные примеры для обучения.

Две библиотеки также можно комбинировать, где Tensorflow Transform используется для анализа и статических преобразований входных данных, а слои предварительной обработки Keras используются для преобразований во время обучения (например, однократное кодирование или увеличение данных).

Рекомендации по использованию tf.distribute

Работа с обоими инструментами включает инициализацию логики преобразования для применения к данным, что может создать ресурсы Tensorflow. Эти ресурсы или состояния должны быть реплицированы для всех рабочих, чтобы сохранить связь между рабочими или рабочими и координаторами.Для этого рекомендуется создать слои предварительной обработки Keras, tft.TFTransformOutput.transform_features_layer или tft.TransformFeaturesLayer под tf.distribute.Strategy.scope , как и для любых других слоев Keras.

В следующих примерах показано использование API tf.distribute.Strategy с высокоуровневым API Keras Model.fit и отдельно с пользовательским циклом обучения.

Слои предварительной обработки и большие словари

При работе с большими словарями (более одного гигабайта) в многопользовательской среде (например, tf.distribute.MultiWorkerMirroredStrategy , tf.distribute.experimental.ParameterServerStrategy , tf.distribute.TPUStrategy ), рекомендуется сохранять словарь в статический файл, доступный для всех воркеров (например, с помощью Cloud Storage). Это сократит время, затрачиваемое на воспроизведение словаря всем работникам во время обучения.

Препроцессинг в конвейере tf.data по сравнению с моделью

В то время как слои предварительной обработки Keras можно применять либо как часть модели, либо непосредственно к tf.data.Dataset , каждый из вариантов имеет свой край:

  • Применение слоев предварительной обработки в модели делает вашу модель переносимой и помогает уменьшить перекос обучения/обслуживания. (Дополнительные сведения см. в разделе «Преимущества предварительной обработки внутри модели во время вывода » в руководстве «Работа со слоями предварительной обработки»)
  • .
  • Применение в конвейере tf.data позволяет выполнять предварительную выборку или разгрузку на ЦП, что обычно повышает производительность при использовании ускорителей.

При работе на одном или нескольких TPU пользователям почти всегда следует размещать слои предварительной обработки Keras в конвейере tf.data , поскольку не все слои поддерживают TPU, а строковые операции не выполняются на TPU. (Двумя исключениями являются tf.keras.layers.Normalization и tf.keras.layers.Rescaling , которые отлично работают на TPU и обычно используются в качестве первого слоя в модели изображения.)

Модель.подходит

При использовании Keras Model.fit не нужно раздавать данные с tf.Distribute.Strategy.experimental_distribute_dataset и tf.distribute.Strategy.distribute_datasets_from_function сами по себе. Подробности см. в руководстве по работе со слоями предварительной обработки и в руководстве по распределенному обучению с помощью Keras. Сокращенный пример может выглядеть следующим образом:

  стратегия = tf.distribute.MirroredStrategy()
со стратегией.scope():
  # Создайте слой(и) под прицелом.
  integer_preprocessing_layer = tf.keras.layers.IntegerLookup (словарь = FILE_PATH)
  модель = ...
  модель.компилировать(...)
набор данных = набор данных.карта (лямбда x, y: (integer_preprocessing_layer (x), y))
model.fit(набор данных)
  

Пользователи tf.distribute.experimental.ParameterServerStrategy с API Model.fit должны использовать tf.keras.utils.experimental.DatasetCreator в качестве входных данных. (Дополнительную информацию см. в руководстве по обучению сервера параметров)

  стратегия = tf.distribute.experimental.ParameterServerStrategy(
    кластер_резолвер,
    Variable_partitioner=variable_partitioner)

со стратегией.объем():
  preprocessing_layer = tf.keras.layers.StringLookup (словарь = FILE_PATH)
  модель = ...
  модель.компилировать(...)

определение набора данных_fn (входной_контекст):
  ...
  набор данных = набор данных.карта (уровень предварительной обработки)
  ...
  вернуть набор данных

dataset_creator = tf.keras.utils.experimental.DatasetCreator(dataset_fn)
model.fit (dataset_creator, эпохи = 5, steps_per_epoch = 20, обратные вызовы = обратные вызовы)

  

Индивидуальный цикл обучения

При написании пользовательского цикла обучения вы будете распространять свои данные либо с помощью файла tf.API распределителя.Strategy.experimental_distribute_dataset или API tf.distribute.Strategy.distribute_datasets_from_function . Если вы распространяете свой набор данных через tf.distribute.Strategy.experimental_distribute_dataset , применение этих API-интерфейсов предварительной обработки в вашем конвейере данных приведет к тому, что ресурсы будут автоматически совмещены с конвейером данных, чтобы избежать удаленного доступа к ресурсам. Таким образом, во всех примерах здесь будет использоваться tf.distribute.Strategy.distribute_datasets_from_function , и в этом случае крайне важно поместить инициализацию этих API в стратегию .scope() для эффективности:

  стратегия = tf.distribute.MirroredStrategy()
vocab = ["а", "б", "в", "г", "ф"]

со стратегией.scope():
  # Создайте слой(и) под прицелом.
  слой = tf.keras.layers.StringLookup (словарь = словарь)

определение набора данных_fn (входной_контекст):
  # tf.data.Набор данных
  набор данных = tf.data.Dataset.from_tensor_slices(["a", "c", "e"]).repeat()

  # Настройте пакетную обработку, сегментирование, предварительную выборку и т. д.
  global_batch_size = 4
  batch_size = input_context.get_per_replica_batch_size (global_batch_size)
  набор данных = набор данных.партия (размер_пакета)
  набор данных = набор данных.осколок(
      input_context.num_input_pipelines,
      input_context.input_pipeline_id)

  # Применяем слой(и) предварительной обработки к tf.data.Dataset
  def preprocess_with_kpl (ввод):
    обратный слой (входной)

  processed_ds = набор данных.карта(preprocess_with_kpl)
  вернуть обрабатываемые_ds

распределенный_набор данных = стратегия.распределить_наборы_данных_из_функции (набор данных_fn)

# Распечатайте несколько примеров пакетов.
Distributed_dataset_iterator = iter (распределенный_набор данных)
для _ в диапазоне (3):
  печать (далее (distributed_dataset_iterator))
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
тф.Тензор ([1 3 0 1], форма = (4,), dtype = int64)
tf.Tensor([3 0 1 3], shape=(4,), dtype=int64)
tf.Tensor([0 1 3 0], shape=(4,), dtype=int64)
 

Обратите внимание, что если вы тренируетесь с tf.distribute.experimental.ParameterServerStrategy , вы также будете вызывать tf.distribute.experimental.coordinator.ClusterCoordinator.create_per_worker_dataset

  @tf.функция
защита per_worker_dataset_fn():
  вернуть Strategy.distribute_datasets_from_function (dataset_fn)

per_worker_dataset = координатор.create_per_worker_dataset (per_worker_dataset_fn)
per_worker_iterator = iter (per_worker_dataset)
  

Для преобразования Tensorflow, как упоминалось выше, этап анализа выполняется отдельно от обучения и поэтому здесь опущен. Подробные инструкции смотрите в учебнике. Обычно этот этап включает создание функции предварительной обработки tf.Transform и преобразование данных в конвейере Apache Beam с помощью этой функции предварительной обработки. В конце этапа анализа выходные данные можно экспортировать в виде графика TensorFlow, который можно использовать как для обучения, так и для обслуживания.Наш пример охватывает только часть конвейера обучения:

.
  со стратегией.scope():
  # working_dir содержит вывод tf.Transform.
  tf_transform_output = tft.TFTransformOutput(рабочий_каталог)
  # Загрузка из work_dir для создания слоя Keras для применения вывода tf.Transform к данным
  tft_layer = tf_transform_output.transform_features_layer()
  ...

определение набора данных_fn (входной_контекст):
  ...
  dataset.map (tft_layer, num_parallel_calls = tf.data.AUTOTUNE)
  ...
  вернуть набор данных

распределенный_набор данных = стратегия.Distribute_datasets_from_function (dataset_fn)
  

Частичные партии

Частичные пакеты встречаются, когда: 1) экземпляры tf.data.Dataset , создаваемые пользователями, могут содержать размеры пакетов, которые не делятся без остатка на количество реплик; или 2) когда мощность экземпляра набора данных не делится на размер пакета. Это означает, что когда набор данных распределен по нескольким репликам, вызов next на некоторых итераторах приведет к tf.ошибки.OutOfRangeError . Для обработки этого варианта использования tf.distribute возвращает фиктивные пакеты размером 0 на репликах, у которых больше нет данных для обработки.

Для случая с одним рабочим, если данные не возвращаются вызовом next итератора, создаются фиктивные пакеты нулевого размера, которые используются вместе с реальными данными в наборе данных. В случае частичных пакетов последний глобальный пакет данных будет содержать реальные данные наряду с фиктивными пакетами данных.Условие остановки обработки данных теперь проверяет, есть ли данные на какой-либо из реплик. Если нет данных ни на одной из реплик, вы получите tf.errors.OutOfRangeError .

В случае с несколькими рабочими процессами логическое значение, представляющее наличие данных на каждом из рабочих процессов, агрегируется с использованием связи между репликами и используется для определения того, все ли рабочие процессы завершили обработку распределенного набора данных. Поскольку это включает в себя взаимодействие между работниками, это приводит к некоторому снижению производительности.

Предостережения

  • При использовании API tf.distribute.Strategy.experimental_distribute_dataset с многопользовательской настройкой вы передаете tf.data.Dataset , который считывается из файлов. Если для tf.data.experimental.AutoShardPolicy установлено значение AUTO или FILE , фактический размер пакета для каждого шага может быть меньше, чем тот, который вы определили для глобального размера пакета. Это может произойти, когда оставшиеся элементы в файле меньше глобального размера пакета.Вы можете либо исчерпать набор данных, не завися от количества выполняемых шагов, либо установить tf.data.experimental.AutoShardPolicy на DATA , чтобы обойти это.

  • Преобразования набора данных с отслеживанием состояния в настоящее время не поддерживаются tf.distribute , и любые операции с отслеживанием состояния, которые может иметь набор данных, в настоящее время игнорируются. Например, если в вашем наборе данных есть map_fn , который использует tf.random.uniform для поворота изображения, то у вас есть график набора данных, который зависит от состояния (т.e случайное начальное число) на локальном компьютере, где выполняется процесс python.

  • Experimental tf.data.experimental.OptimizationOptions , отключенные по умолчанию, могут в определенных контекстах, например, при использовании вместе с tf.distribute , вызывать снижение производительности. Их следует включать только после того, как вы подтвердите, что они улучшают производительность вашей рабочей нагрузки в настройках распространения.

  • Обратитесь к этому руководству, чтобы узнать, как оптимизировать конвейер ввода с помощью tf.данные в общем. Несколько дополнительных советов:

    • Если у вас есть несколько рабочих процессов и вы используете tf.data.Dataset.list_files для создания набора данных из всех файлов, соответствующих одному или нескольким шаблонам шаблонов, не забудьте установить аргумент seed или установить shuffle = False , поэтому чтобы каждый рабочий сегментировал файл последовательно.

    • Если ваш входной конвейер включает в себя как перетасовку данных на уровне записи, так и синтаксический анализ данных, если не проанализированные данные значительно больше, чем проанализированные данные (что обычно не так), сначала перемешайте, а затем проанализируйте, как показано в следующем пример.Это может улучшить использование памяти и производительность.

  d = tf.data.Dataset.list_files (шаблон, перемешивание = False)
d = d.shard (число_работников, рабочий_индекс)
d = d.repeat (число_эпох)
d = d.shuffle(shuffle_buffer_size)
d = d.interleave(tf.data.TFRecordDataset,
                 cycle_length=num_readers, block_length=1)
d = d.map (parser_fn, num_parallel_calls = num_map_threads)
  
  • tf.data.Dataset.shuffle(buffer_size, seed=None, reshuffle_each_iteration=None) поддерживает внутренний буфер из buffer_size элементов, и, таким образом, уменьшение buffer_size может уменьшить проблему OOM.

  • Порядок обработки данных рабочими процессами при использовании tf.distribute.experimental_distribute_dataset или tf.distribute.distribute_datasets_from_function не гарантируется. Обычно это требуется, если вы используете tf.distribute для предсказания масштаба. Однако вы можете вставить индекс для каждого элемента в пакете и соответствующим образом упорядочить выходные данные. Следующий фрагмент является примером того, как упорядочить выходные данные.

Примечание: тс.Для удобства здесь использована функция Distribute.MirroredStrategy . Вам нужно изменить порядок входных данных только при использовании нескольких рабочих процессов, но tf.distribute.MirroredStrategy используется для распределения обучения по одному рабочему процессу.
  mirrored_strategy = tf.distribute.MirroredStrategy()
размер_набора данных = 24
размер_пакета = 6
набор данных = tf.data.Dataset.range(dataset_size).enumerate().batch(batch_size)
dist_dataset = зеркальная_стратегия.experimental_distribute_dataset(набор данных)

def прогнозировать (индекс, входы):
  выходы = 2 * входы
  возвращаемый индекс, выходы

результат = {}
для индекса входные данные в dist_dataset:
  output_index, outputs = зеркальная_стратегия.запустить (предсказать, аргументы = (индекс, входные данные))
  индексы = список (mirrored_strategy.experimental_local_results (output_index))
  риндес = []
  для a в индексах:
    rindices.extend(a.numpy())
  выходы = список (mirrored_strategy.experimental_local_results (результаты))
  выходы = []
  для выходов:
    rouputs.extend(a.numpy())
  для i значение в zip(rindices, rouputs):
    результат[я] = значение

печать (результат)
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
ПРЕДУПРЕЖДЕНИЕ:tensorflow:использование MirroredStrategy в настоящее время имеет значительные накладные расходы.Мы будем работать над улучшением этого в будущем, но сейчас, пожалуйста, оберните `call_for_each_replica`, `experimental_run` или `run` внутри tf.function, чтобы получить наилучшую производительность.
ПРЕДУПРЕЖДЕНИЕ:tensorflow:использование MirroredStrategy в настоящее время имеет значительные накладные расходы. Мы будем работать над улучшением этого в будущем, но сейчас, пожалуйста, оберните `call_for_each_replica`, `experimental_run` или `run` внутри tf.function, чтобы получить наилучшую производительность.
ПРЕДУПРЕЖДЕНИЕ:tensorflow:использование MirroredStrategy в настоящее время имеет значительные накладные расходы.Мы будем работать над улучшением этого в будущем, но сейчас, пожалуйста, оберните `call_for_each_replica`, `experimental_run` или `run` внутри tf.function, чтобы получить наилучшую производительность.
ПРЕДУПРЕЖДЕНИЕ:tensorflow:использование MirroredStrategy в настоящее время имеет значительные накладные расходы. Мы будем работать над улучшением этого в будущем, но сейчас, пожалуйста, оберните `call_for_each_replica`, `experimental_run` или `run` внутри tf.function, чтобы получить наилучшую производительность.
{0&двоеточие; 0, 1&двоеточие; 2, 2&двоеточие; 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18, 10: 20, 11: 22, 12: 24, 13: 26, 14: 28, 15: 30, 16: 32, 17: 34, 18: 36, 19: 38, 20: 40, 21: 42, 22: 44, 23: 46}
2022-03-26 01:22:21.7: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:776] Политика сегментации AUTO будет применять политику сегментации DATA, поскольку не удалось применить политику сегментации FILE по следующей причине: Найден нерасчленяемый исходный набор данных: имя&двоеточие; "Диапазондатасет/_3"
оп&колон; "RangeDataset"
ввод&двоеточие; "Пост/_4"
ввод&двоеточие; "Пост/_1"
ввод&двоеточие; "Пост/_16"
атрибут {
  ключ&двоеточие; "_кардинальность"
  ценность {
    я&двоеточие; 9223372036854775807
  }
}
атрибут {
  ключ&двоеточие; "метаданные"
  ценность {
    с&двоеточие; "\n\020RangeDataset:168"
  }
}
атрибут {
  ключ&двоеточие; "output_shapes"
  ценность {
    список {
      форма {
      }
    }
  }
}
атрибут {
  ключ&двоеточие; "выходные_типы"
  ценность {
    список {
      тип&двоеточие; DT_INT64
    }
  }
}
экспериментальный_тип {
  type_id: TFT_PRODUCT
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_INT64
        }
      }
    }
  }
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_INT64
        }
      }
    }
  }
}
 

Тензорные входы вместо tf.данные

Иногда пользователи не могут использовать tf.data.Dataset для представления своего ввода, а затем вышеупомянутые API для распространения набора данных на несколько устройств. В таких случаях вы можете использовать необработанные тензоры или входные данные от генератора.

Использовать Experiment_distribute_values_from_function для произвольных тензорных входов

Strategy.run принимает tf.distribute.DistributedValues ​​, который является результатом следующий(итератор) . Чтобы передать значения тензора, используйте тс.распределить.Strategy.experimental_distribute_values_from_function для построения tf.distribute.DistributedValues ​​ из необработанных тензоров. С этой опцией пользователь должен будет указать свою собственную логику пакетной обработки и сегментирования во входной функции, что можно сделать с помощью входного объекта tf.distribute.experimental.ValueContext .

  mirrored_strategy = tf.distribute.MirroredStrategy()

определение значение_fn (ctx):
  вернуть tf.constant (ctx.replica_id_in_sync_group)

распределенные_значения = зеркальная_стратегия.Experiment_distribute_values_from_function(value_fn)
для _ в диапазоне (4):
  результат = mirrored_strategy.run (лямбда x: x, args = (distributed_values,))
  печать (результат)
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
ПРЕДУПРЕЖДЕНИЕ:tensorflow:использование MirroredStrategy в настоящее время имеет значительные накладные расходы. Мы будем работать над улучшением этого в будущем, но сейчас, пожалуйста, оберните `call_for_each_replica`, `experimental_run` или `run` внутри tf.функцию для достижения наилучшей производительности.
tf.Tensor(0, shape=(), dtype=int32)
tf.Tensor(0, shape=(), dtype=int32)
tf.Tensor(0, shape=(), dtype=int32)
tf.Tensor(0, shape=(), dtype=int32)
 

Используйте tf.data.Dataset.from_generator, если вы вводите данные из генератора

Если у вас есть функция генератора, которую вы хотите использовать, вы можете создать экземпляр tf.data.Dataset , используя API from_generator .

Примечание: В настоящее время не поддерживается для tf.распределить.TPUStrategy .
  mirrored_strategy = tf.distribute.MirroredStrategy()
определение input_gen():
  пока верно:
    выход np.random.rand(4)

# использовать Dataset.from_generator
набор данных = tf.data.Dataset.from_generator(
    input_gen, output_types=(tf.float32), output_shapes=tf.TensorShape([4]))
dist_dataset = зеркальная_стратегия.experimental_distribute_dataset(набор данных)
итератор = итератор (dist_dataset)
для _ в диапазоне (4):
  результат = mirrored_strategy.run (лямбда x: x, аргументы = (следующий (итератор)))
  печать (результат)
  
INFO:tensorflow:использование MirroredStrategy с устройствами ('/job:localhost/replica:0/task:0/device:GPU:0',)
тф.Тензор([0,3663752 0,67770004 0,5307119 0,02984766], shape=(4,), dtype=float32)
tf.Tensor([0.38887537 0.7951679 0.9167635 0.92619467], shape=(4,), dtype=float32)
tf.Tensor([0.8601577 0.39343187 0.5286574 0.8947321 ], shape=(4,), dtype=float32)
tf.Tensor([0.97357106 0.3202021 0.5932173 0.8580977 ], shape=(4,), dtype=float32)
2022-03-26 01:22:22.137829: W tensorflow/core/grappler/optimizers/data/auto_shard.cc:776] Политика сегментации AUTO будет применять политику сегментации DATA, поскольку не удалось применить политику сегментации FILE по следующей причине: Не нашел фрагментируемый источник, перешел к узлу, который не является набором данных: имя&двоеточие; "Набор данных FlatMap/_2"
оп&колон; «Набор данных плоской карты»
ввод&двоеточие; "TensorDataset/_1"
атрибут {
  ключ&двоеточие; "Таргументы"
  ценность {
    список {
    }
  }
}
атрибут {
  ключ&двоеточие; "_кардинальность"
  ценность {
    я&двоеточие; -2
  }
}
атрибут {
  ключ&двоеточие; "ф"
  ценность {
    функция {
      имя&двоеточие; "__inference_Dataset_flat_map_flat_map_fn_3998"
    }
  }
}
атрибут {
  ключ&двоеточие; "метаданные"
  ценность {
    с&двоеточие; "\n\022FlatMapDataset:184"
  }
}
атрибут {
  ключ&двоеточие; "output_shapes"
  ценность {
    список {
      форма {
        тусклый {
          размер&двоеточие; 4
        }
      }
    }
  }
}
атрибут {
  ключ&двоеточие; "выходные_типы"
  ценность {
    список {
      тип&двоеточие; DT_FLOAT
    }
  }
}
экспериментальный_тип {
  type_id: TFT_PRODUCT
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
  аргументы {
    type_id: TFT_DATASET
    аргументы {
      type_id: TFT_PRODUCT
      аргументы {
        type_id: TFT_TENSOR
        аргументы {
          type_id: TFT_FLOAT
        }
      }
    }
  }
}
.Рассмотрите возможность отключения автоматического сегментирования или переключения auto_shard_policy на DATA, чтобы сегментировать этот набор данных. Вы можете сделать это, создав новый объект `tf.data.Options()`, затем установив `options.experimental_distribute.auto_shard_policy = AutoShardPolicy.DATA` перед применением объекта параметров к набору данных через `dataset.with_options(options)`.
 

Конфигурация устройства ввода — Fedora Project Wiki

Как правило, пользователям рекомендуется использовать специальные инструменты настройки рабочего стола (например,грамм. гном-центр управления). Для параметров, которые не доступны в среде рабочего стола, наилучшим подходом является фрагмент конфигурации xorg.conf.d InputClass.

X-сервер поддерживает каталоги конфигурации /etc/X11/xorg.conf.d и /usr/share/X11/xorg.conf.d . Первый предназначен для пользовательской конфигурации, а второй предоставляет конфигурации поставщиками дистрибутивов. Изменения файлов в последнем каталоге могут быть перезаписаны. Далее основное внимание уделяется пользовательскому каталогу конфигурации.

Файлы с суффиксом .conf в этом каталоге анализируются X-сервером при запуске и обрабатываются как часть традиционного файла конфигурации xorg.conf. Файлы в этом каталоге могут содержать один или несколько разделов; описание опций в разделе и общий вид смотрите в xorg.conf(5). Файлы в каталоге /etc/X11/xorg.conf.d анализируются в порядке до того, как xorg.conf будет полностью проанализирован , при этом приоритет отдается файлу xorg.conf, а затем к последней записи конфигурации, где это применимо. По сути, X-сервер обрабатывает набор файлов конфигурации как один большой файл с записями из xorg.conf в конце. Пользователям рекомендуется поместить пользовательскую конфигурацию в /etc/X11/xorg.conf и оставить каталог для фрагментов конфигурации, предоставленных дистрибутивом.

Входные классы

InputClasses применяются к классу устройств, включая устройства с возможностью горячей замены. Область действия раздела InputClass ограничена совпадением с указанным — для применения к устройству ввода все совпадения должны применяться к устройству.Пример раздела InputClass приведен ниже:

 Раздел "InputClass"
   Идентификатор "сенсорная панель"
   MatchIsTouchpad "включен"
   Драйвер "libinput"
EndSection
 

Если присутствует этот фрагмент, любая сенсорная панель назначается драйверу libinput. Обратите внимание, что из-за порядка приоритета (буквенно-цифровая сортировка фрагментов xorg.conf.d) настройка драйвера перезаписывает ранее установленные параметры драйвера — чем более общий класс, тем раньше он должен быть указан. Фрагмент по умолчанию, поставляемый с пакетом xorg-x11-drv-Xorg, — 00-evdev.conf и применяет драйвер evdev ко всем устройствам ввода.

Параметры соответствия определяют, к каким устройствам может применяться раздел. Для сопоставления устройства должны применяться все строки соответствия. Поддерживаются следующие строки соответствия (с примерами):

  • MatchIsPointer, MatchIsKeyboard, MatchIsTouchpad, MatchIsTouchscreen, MatchIsJoystick — логические параметры для применения к группе устройств.
  • MatchProduct "foo|bar": сопоставить любое устройство с названием продукта, содержащим либо "foo", либо "bar"
  • MatchVendor "foo|bar|baz": сопоставьте любое устройство со строкой поставщика, содержащей либо "foo", "bar", либо "baz"
  • MatchDevicePath "/dev/input/event*": сопоставить любое устройство с путем, соответствующим данному патчу (см. fnmatch(3) для разрешенного шаблона)
  • MatchTag "foo|bar": соответствует любому устройству с тегом "foo" или "bar".Теги могут быть назначены серверной частью конфигурации — в нашем случае udev — для маркировки устройств, которые нуждаются в специальной настройке.

Пример раздела пользовательской конфигурации:

 Раздел "InputClass"
   Идентификатор "замедление лазерной мыши"
   MatchIsPointer "включен"
   MatchProduct "Лазерная мышь"
   MatchVendor "LaserMouse Inc."
   Опция «Постоянное замедление» «20»
EndSection
 

Этот раздел будет соответствовать стрелочному устройству, содержащему «Lasermouse» от «Lasermouse Inc." и примените постоянное замедление 20 к этому устройству - замедление его в 20 раз. Информация, необходимая для MatchIsPointer и других ключевых слов соответствия, поступает из /lib/udev/input-id . [1] Он проверяет возможности устройства и назначает ряд переменных, затем сервер проверяет эти переменные, чтобы определить совпадение. Проверьте вывод «udevadm info --export-db | grep ID_INPUT» для переменных, назначенных вашим устройствам ввода.

Особые требования к устройствам Wacom

Устройства, управляемые xorg-x11-drv-wacom, имеют особые требования к конфигурации.Этот драйвер создаст несколько X-устройств из одного устройства ядра. Все устройства можно настраивать, но драйвер меняет имя в соответствии с инструментом. Например, «Wacom Intuos4 6x9» (имя ядра) будет отображаться как «стилус Wacom Intuos4 6x9», «ластик Wacom Intuos4 6x9» и т. д. Для фрагментов xorg.conf.d «стилус» не может быть сопоставлен. , применяется после того, как сервер увидит устройство. Вы можете сопоставить «ластик» и другие инструменты.

Если у вас есть определенная конфигурация, которая должна применяться только к стилусу, но не к другим устройствам, вы должны настроить несколько фрагментов конфигурации, один из которых соответствует «Wacom Intuos4 6x9», чтобы применить настройку стилуса, а другие отменяют эту настройку для другие устройства.

Добавление устройства в черный список

Некоторые устройства могут быть обнаружены X-сервером, хотя этого быть не должно. Эти устройства можно настроить так, чтобы они игнорировались:

 Раздел "InputClass"
   Идентификатор "нет необходимости в акселерометрах в X"
   MatchProduct "акселерометр"
   Опция «Игнорировать» «включена»
EndSection
 

системный адрес

В F18 и более поздних версиях systemd-localed отвечает за настройку раскладки клавиатуры. Основной файл — /etc/vconsole.conf, и любые изменения в этом файле будут отражены в /etc/X11/xorg.conf.d/00-keyboard.conf. Обратите внимание, что изменения общесистемного макета не будут применяться до перезапуска X. Используйте localectl для изменения настроек клавиатуры. Например, чтобы изменить макет по умолчанию на нас с опцией завершения сервера, используйте:

 localectl set-x11-keymap "нас" "" "" "завершение: ctrl_alt_bksp"
 

Аргументы: макет, модель, вариант, опции, и любой пустой аргумент просто игнорируется (в данном случае модель и вариант).

Вы можете проверить, работает ли systemd-localed с помощью команды

 статус systemctl systemd-localed.услуга
 

клавиатура настройки системы

Для Fedora 18 и более поздних версий см. #systemd-localed.

До Fedora 17 пакет system-setup-keyboard (ранее fedora-setup-keyboard) — это служба, работающая на уровне запуска 5, которая отслеживает изменения в /etc/sysconfig/keyboard . Если происходит изменение, он преобразует информацию во фрагмент xorg.conf.d, который служит конфигурацией клавиатуры по умолчанию (обычно /etc/X11/xorg.conf.d/00-system-setup-keyboard.conf). Не редактируйте сгенерированный файл, так как ваши изменения будут перезаписаны при каждом изменении /etc/sysconfig/keyboard.Если вы хотите изменить раскладку клавиатуры по умолчанию, просто переименуйте файл и примените свои пользовательские параметры.

Пример конфигурации

В следующих подразделах описаны примеры конфигураций для часто используемых варианты конфигурации. Обратите внимание, что если вы используете среду рабочего стола, такую ​​как GNOME или KDE, параметры, установленные в xorg.conf , могут быть перезаписаны с помощью пользовательские параметры при входе в систему. Обратите внимание, что файлы конфигурации зависит от драйвера.

Пример: эмуляция колеса (для трекпойнта)

Этот параметр применим только к xorg-x11-drv-evdev. Эмуляция колеса доступен по умолчанию с помощью xorg-x11-drv-libinput.

Если у вас есть компьютер с трекпойнтом (например, Thinkpad), вы можете добавить в xorg.conf следующее, чтобы использовать среднюю кнопку для эмуляции колесика мыши:

 Раздел "InputClass"
   Идентификатор "Эмуляция колеса"
   MatchIsPointer "включен"
   МатчПродукт "TrackPoint"
   Опция «ЭмулироватьWheelButton» «2»
   Опция "EmulateWheel" включена
EndSection
 

Пример: касание и щелчок

Касание и щелчок можно включить в диалоговом окне конфигурации мыши (на вкладке сенсорной панели), но если вам нужно включить касание в gdm, следующий фрагмент кода включит его для вас:

 # Для xorg-x11-drv-libinput
Раздел "Входной класс"
       Идентификатор "тап по умолчанию"
       MatchIsTouchpad "включен"
       MatchDriver "libinput"
       Опция «Нажатие» «вкл.»
EndSection

# Для xorg-x11-drv-synaptics
Раздел "Входной класс"
       Идентификатор "тап по умолчанию"
       MatchIsTouchpad "включен"
       MatchDriver "синаптика"
       Опция "TapButton1" "1"
EndSection
 

Пример: включение ClickPad

Этот параметр применяется только к xorg-x11-drv-synaptics. Не нужен под xorg-x11-drv-libinput, который автоматически определяет сенсорные панели.

Многие новые ноутбуки оснащены так называемыми ClickPads, сенсорными панелями без физических кнопок. Вместо этого вся тачпад работает как кнопка. Примеры таких тачпадов можно найти на ноутбуках Lenovo серии x220 и Apple. ClickPads поддерживаются только в Fedora 17 и более поздних версиях. [2] Устройства ClickPad обнаруживаются автоматически, но если ваше устройство не обнаружено, приведенный ниже фрагмент включает его.

 Раздел "InputClass"
       Идентификатор "force clickpad"
       MatchProduct "подстрока имени устройства"
       Опция «ClickPad» «включена»
       # Включить правую нижнюю половину как правую кнопку
       Опция «SoftButtonAreas» «50% 0 82% 0 0 0 0 0»
EndSection
 

Пример: инверсия оси

Этот параметр применим только к xorg-x11-drv-evdev.

В некоторых устройствах, особенно во встроенных сенсорных планшетах, сенсорная рамка установлена ​​повернутой или перевернутой. Для этих устройств добавьте следующий фрагмент, адаптированный к имени вашего устройства (получите его с помощью xinput --list). Раскомментируйте то, что не подходит

 Раздел "InputClass"
       Идентификатор "инверсия оси"
       MatchProduct "подстрока имени устройства"
       # поменять местами оси x/y на устройстве. то есть повернуть на 90 градусов
       Опция "SwapAxes" включена
       # Инвертировать соответствующую ось.Опция «InvertX» «включена»
       Опция "InvertY" включена
EndSection
 

Правильную комбинацию настроек можно проверить во время выполнения с помощью xinput команда.

 # переключить своп осей
 $> xinput --set-prop "<имя устройства>" "Evdev Axes Swap" 1
 # инвертировать X, а не Y
 $> xinput --set-prop "<имя устройства>" "Инверсия оси Evdev" 1 0
 # инвертировать Y, а не X
 $> xinput --set-prop "<имя устройства>" "Инверсия оси Evdev" 0 1
 

gdm и GNOME

Конфигурация клавиатуры GNOME перезапишет конфигурацию клавиатуры, установленную в xorg.conf — после завершения процесса входа в систему. Таким образом, когда-то клавиатура конфигурация установлена ​​в сеансе GNOME, изменение xorg.conf будет иметь мало влияет на раскладку клавиатуры.

С другой стороны, раскладка, выбранная вручную в gdm, будет перенесена в сеанс в качестве дополнительной раскладки клавиатуры. Таким образом, если вы выберете «нас» в gdm для входа в систему, а затем "de" в сеансе GNOME, действующая раскладка клавиатуры для будущих сессий "de,us". Чтобы избежать этого, выберите клавиатуру по умолчанию. расположение в gdm (см. Bug 602145).

Решение для gdm, отменяющего настройки Xorg, было разработано с помощью пользовательской конфигурации устройства ввода в GNOME. Затем можно установить параметр dconf org.gnome.settings-daemon.peripherals.input-devices hotplug-command на полное имя пользовательского сценария, который запускается при каждом событии устройства ввода. Пример того, как сделать Yubikey всегда с «американской» раскладкой (даже если остальная часть системы не является американской), был представлен в этом блоге.

X-серверы, представленные в Fedora 9 и более поздних версиях, используют HAL для получения списка устройств ввода.Всякий раз, когда X-сервер запускается, он запрашивает у HAL список устройств ввода и добавляет каждое из них с соответствующим драйвером. Всякий раз, когда подключается новое устройство ввода или удаляется существующее устройство ввода, HAL уведомляет X-сервер о наличии или удалении устройства. Из-за этой системы уведомлений некоторые устройства, настроенные в xorg.conf, игнорируются X-сервером (все устройства, использующие драйвер «мышь», «kbd» или «vmmouse»).

Помимо сигнализации о наличии нового устройства, HAL также предоставляет X-серверу ряд опций для каждого устройства.В частности, это включает в себя драйвер, который сервер должен загрузить, и файл устройства, который нужно открыть. Он также позволяет использовать дополнительные пользовательские параметры конфигурации.

Конфигурация устройства

Fedora предоставляет список конфигураций по умолчанию в /usr/share/hal/fdi/policies/10osvendor/10-x11-input.fdi и некоторые конфигурации для конкретных драйверов в /usr/share/hal/fdi/policies/ 20третьих сторон/10-synaptics.fdi . Не редактируйте эти файлы напрямую, так как они будут перезаписаны при следующем обновлении.Вместо этого сначала скопируйте файл в /etc/hal/fdi/policy , а затем отредактируйте его соответствующим образом. Например, fdi для сенсорной панели Synaptics может выглядеть так:

 
<версияинформации об устройстве="0.2">
  <устройство>
    
        синаптика
        1
    
  

 

Приведенный выше XML-файл определяет следующее: если устройство представляет собой сенсорную панель (HAL назначает эту возможность автоматически), загрузите драйвер synaptics X11 для этого устройства.Ключ input.x11_driver интерпретируется сервером. Вторая команда слияния указывает, что параметр TapButton1 со значением «1» должен быть передан драйверу. Любой ключ input.x11_options интерпретируется драйвером и эквивалентен традиционной форме Опция «Имя опции» «Значение опции» в файле xorg.conf. На справочной странице соответствующего драйвера перечислены доступные параметры. Обратите внимание, что любой ключ input.x11_options должен иметь тип «строка», даже если он обозначает число.Другие типы будут игнорироваться сервером.

Команды слияния являются аддитивными. Например, файл fdi, предоставляемый пакетом xorg-x11-drv-synaptics, содержит ключ input.x11_driver . Пользовательская конфигурация не требует повторного указания этого ключа и вместо этого должна предоставлять только локальные параметры конфигурации, такие как параметр TapButton1 выше.

Чтобы удалить существующий ключ, можно использовать следующий синтаксис:

 
  <версияинформации об устройстве="0.2">
    <устройство>
      
         <удалить ключ="input.x11_driver">
      
     
  
 

Этот фрагмент удаляет ключ input.x11_driver со всех устройств, содержащих строку «Случайная строка». Как указано выше, input.x11_driver — это специальный ключ, и его удаление не позволяет X-серверу добавить это устройство. Тот же синтаксис может использоваться для удаления других опций.

Просмотр изменений конфигурации

В крайнем случае неправильная конфигурация драйверов ввода может привести к тому, что X-сервер не будет иметь устройств ввода. Перед перезапуском сервера важно просмотреть изменения в файлах fdi, чтобы убедиться, что по крайней мере некоторые устройства доступны.

После редактирования файлов fdi демон HAL можно перезапустить с помощью service haldaemon restart . После успешного перезапуска можно использовать lshal для получения списка всех устройств и их конфигураций.Как правило, по крайней мере на одном клавиатурном устройстве для параметра input.x11_driver должно быть задано значение «evdev», чтобы разрешить ввод с клавиатуры в случае сбоя всех других конфигураций.

Отключение использования HAL

Некоторые пользователи хотят отключить использование HAL. X-сервер предоставляет две возможности для достижения этой цели:

  • Опция "AutoAddDevices" "false"

Если эта опция отключена, то никакие устройства не будут добавляться из событий HAL. Обратите внимание, что если этот параметр отключен, AllowEmptyInput также автоматически отключается, если только пользователь явно не включил его.

  • Опция "AllowEmptyInput" "false"

Если AllowEmptyInput имеет значение false, сервер проверяет наличие основных устройств в xorg.conf (опция "CorePointer" и опция "CoreKeyboard"). Если ни один из них не присутствует и не упоминается в разделе ServerLayout, сервер автоматически добавляет первое устройство мыши и клавиатуры в xorg.conf или, если ни одно из них не присутствует, жестко закодированные устройства ввода по умолчанию. Отключение AllowEmptyInput также заставляет сервер учитывать устройства, использующие драйверы «мышь», «kbd» и «vmmouse» (эти устройства игнорируются по умолчанию).

В большинстве случаев простое отключение AutoAddDevices — правильный способ отключить использование HAL. Обратите внимание, что если AllowEmptyInput выключен, а AutoAddDevices включен, то устройства могут быть добавлены несколько раз (один раз, как указано в xorg.conf, и один раз, как указано в HAL). Это приводит к дублированию нажатий кнопок и тройному нажатию клавиш.

.

Добавить комментарий

Ваш адрес email не будет опубликован.