AlphaZero. Нейронная сеть играет в шахматы

Тема в разделе "Машинное отделение", создана пользователем grizly, 6 дек 2017.

  1. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    8.926
    Симпатии:
    2.107
    Репутация:
    84
    Адрес:
    Москва
    Оффлайн
    А нельзя веса из старой сети каким-то образом перенести в новую (если размер больше, то как-то интерполировать, что ли). Чтобы с нуля заново не начинать?
  2. pavelgttfj8 Учаcтник

    • Участник
    Рег.:
    07.12.2017
    Сообщения:
    150
    Симпатии:
    48
    Репутация:
    2
    Оффлайн
  3. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    Оценка в вероятностях победы, ничьи и поражения намного адекватнее и понятнее, чем в пешках. И собственно в докомпьютерную эпоху оценка такой и была - плюс-минус, плюс-минус в столбик, равная, ничейная, игра на три результата. Это все вероятностные оценки. Просто переборные движки только пешки умеют выдавать, поэтому это и стало стандартом. Подвинут нейронные движки переборные, стандарт изменится.
    —- добавлено: 25 авг 2018 —-
    Значит оценка вовсе не 0.00. Вероятность белых победить выше.
  4. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    Не факт. Лила на бюджетной видяхе вчера достойно сопротивлялась Стокфишу 8, играющему на суперпроцах. 4 : 8 проиграла в длинный блиц. Будь у Стокфиша тоже бюджетное железо играли бы на равных. То есть уже и на рядовом компе переборные и нейронные движки сопоставимы по силе. При этом переборные движки уже сколько вылизывают, а для нейронных это первый опыт. Запас для прогресса там еще большой должен быть.
  5. Sergey1983 Учаcтник

    • Участник
    Рег.:
    03.04.2018
    Сообщения:
    126
    Симпатии:
    14
    Репутация:
    1
    Оффлайн
    А на какой именно видеокарте она играла и какой счёт был в конце?
  6. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    8.926
    Симпатии:
    2.107
    Репутация:
    84
    Адрес:
    Москва
    Оффлайн
    Оценка - это только приближение к истинному value позиции. В крестиках ноликах 3 на 3 это value равно строго 0.5 (доказано элементарных перебором), в игре пять в ряд без фолов - 1.0 для чёрных. В шахматах value равно 0.5 (пока не доказано, но крайне правдоподобно), и никакого отношения к вероятности оно не имеет.
  7. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    Не знаю на какой карте. Но скорость была 1.7 килоноды в секунду. Для сравнения. Скорость на спарке GTX 1080 сложно оценить из-за перегрева. Примерно получается так - 150 кнод/с при времени обдумывания 8 секунд, 60 кнод/с при 15 секундах, 20 кнод/с при минуте. То есть на полной мощности скорость должна была быть в сотни кнод/с, а из-за перегрева Лила фактически играла на 10% мощности.

    В первом приближении мощность вчерашней видяхи 1/100 от спарки GTX 1080, т.е. жалкие 180 ГФлопс. Для сравнения у GT 710 за 3 тысячи рублей производительность 360 ГФлопс. То есть походу Лила вчера вообще на встроенной в проц видяхе играла.

    По счету примерно так и закончилось. После 12 партий на 3 партии подключили, то что здесь на форуме было анонсировано как V100. Но скорость поднялась аж до 27 кнод/с, т.е. это явно не V100 была. Все партии закончились в ничью. Потом снова вернули бюджетный вариант, первую Лила проиграла, а дальше я не смотрел. Но там почти сразу и закончилась. Так разница между Стокфишем 8 на суперпроцах и Лилой на чем-то очень бюджетном получилась в 150 пунктов рейтинга.
  8. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    8.926
    Симпатии:
    2.107
    Репутация:
    84
    Адрес:
    Москва
    Оффлайн
    Почему-то все результаты Лилы сопровождаются частицами "бы", "когда", "если" и т. д. Неужели среди энтузиастов нет никого, кто мог бы запустить её на по-настоящему мощном железе и сделать этого Стокфиша хотя бы со счётом 10-0 ? То, что в сферическом вакууме Лила - чемпион галактики, все поняли уже давно. А в реале Арасана не обыгрывает...
  9. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    А кто знает, для переборных движков десятикратное увеличение производительности какой прирост силы игры дает?
    —- добавлено: 25 авг 2018, опубликовано: 25 авг 2018 —-
    А кто говорит о чемпионе галактики? Насколько можно судить пока сила Лилы на видяхе сопоставима силе переборных движков на соответствующем видяхе по цене проце. Вот на V100 Лила по идее уже должна доминировать, потому что это не видяха, а оптимизированная под нейровычисления штуковина, соответственно она в 2-3 раза производительнее видях при той же цене и энергопотреблении. Но V100 10 килобаксов стоит, как-то дороговато для энтузиастов.
  10. svoitsl Учаcтник

    • Участник
    Рег.:
    05.01.2018
    Сообщения:
    157
    Симпатии:
    28
    Репутация:
    1
    Оффлайн
    А почему вы думаете,что перегрев все ещё актуален,может его уже давно устранили,благо время на это было
    тут вроде указана скорость без всякого перегрева,и вообще эти GPU довольно популярны и на перегрев ни кто не жаловался

    Не знаю точно сколько моя GT 730 дает Gflops,но nps я думаю порядка 500-600

    Ну прям уж настоящее мощное железо мало к кого есть, но если ума нет (в смысле хорошей сети), то железо не поможет, Lc0 запускали уж на 4ХV100 (примерно как 4 TPU Гугла) в тестах CCCC, но это ей не помогло.

    но опять таки с "частицами "бы", "когда", "если" и т. д."
    ТО есть не сейчас, и наверно не в этом году, но в будущем (не году, в просто) вполне вероятно
  11. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    Сами посмотрите по архиву игр. Четкая зависимость. Когда Лила тратила на ход порядка 10 секунд, то скорость была 40-100 кнод/с. А когда порядка минуты, то 15-20 кнод. Скорей всего это как раз перегревом объясняется. За время хода соперника видеокарта остывала, затем сколько-то секунд выдавала около пиковую производительность, потом нагревалась и начинала работать еле-еле. Хотя есть другое объяснение. Что это из-за кэшированных с предыдущего хода позиций скорость поначалу такая высокая. Поэтому не так все ясно, как казалось. :)

    По таблице получается, что связка TITAN V + TITAN XP суммарной производительностью 27 ГФлопс выдает 79 кнод/с. Соответственно спарка 1080 суммарной производительностью 18 ГФлопс должна выдавать порядка 50 кнод/с, а вовсе не те 15-20 кнод/с, которые мы видели на чемпионате. Плюс суперпроц еще должен какой-то прирост был дать, запихивает данные в видеокарту он явно быстрее настольного. Тогда получается, что Лила фактически играла на 30% мощности видеокарт.
  12. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Зависит от того, с какого контроля стартует десятикратное увеличение. Если грубо, то даже двукратное увеличение даёт примерно +100 эло в блице и +50 эло на длинных контролях на одном ядре. Если надо точнее, то вот:
    http://www.fastgm.de/time-control4.html

    Вот тесты на приличном и до некоторой степени сбалансированном железе (правда проц всего лишь четырехядерный):
    https://docs.google.com/spreadsheet...USx1jyUrgVEcj8DNLKA7-urBw/edit#gid=1316991135

    Конечно блиц, но node per move достаточно приличный. По масштабированию можно посмотреть здесь, в таблице (для большой и средней сети):
    https://docs.google.com/spreadsheet...USx1jyUrgVEcj8DNLKA7-urBw/edit#gid=1392971980
    Undying нравится это.
  13. svoitsl Учаcтник

    • Участник
    Рег.:
    05.01.2018
    Сообщения:
    157
    Симпатии:
    28
    Репутация:
    1
    Оффлайн
    как вы можете видеть по той же таблице 10 GTX1080 Ti дают 30 knps, вряд ли можно ждать, что две дадут 50 knps.
  14. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    Судя по таблице вчера Лила играла на чем-то вроде GTX 950. То есть на видяхе за 150 баксов против суперпроцов за 8 килобаксов. При этом разница в силе игры всего 150 пунктов. Наглядное свидетельство того, что уже и на бюджетных компах Лила будет сопоставима по силе с топовыми переборными движками.
  15. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Там кто-то всю таблицу изуродовал. У Titan V было 31 knps; у Titan V + XP было 37 knps; у 1080ti было 8,5 knps; у 4xV100 было 78 knps.

    У 1080ti скорость мала, потому что не поддерживается половинная точность и нет тензорных ядер. У 4xV100 скорость невелика, потому что нет поддержки игры на четырех видеокартах.
  16. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    По таблице можно только очень грубо судить. Там даже проц не указан и правильно ли настраивали вопрос. Но по логике надо на максимальные результаты ориентироваться, т.к. на чемпионате и проц был супер и настройки правильные.
  17. svoitsl Учаcтник

    • Участник
    Рег.:
    05.01.2018
    Сообщения:
    157
    Симпатии:
    28
    Репутация:
    1
    Оффлайн
    Может и так, но все таки на СССС она вполне уверено давала 70-80 knps, что примерно равно 4TPU Гугла, что правда LC0 не сильно помогло.
    Хотя и пишут что поддержка мультиGPU не поная
  18. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Чтобы не учитывалось кеширование нужно смотреть скорость на первом самостоятельном ходу в партии.
    —- добавлено: 25 авг 2018 —-
    Ну правильно, те же 78 knps, что и в бенче. По масштабированию на 4 карты crem писал:
    http://talkchess.com/forum3/viewtopic.php?f=2&t=68253&p=772023#p772023
    Undying нравится это.
  19. Undying Учаcтник

    • Участник
    Рег.:
    31.08.2016
    Сообщения:
    862
    Симпатии:
    386
    Репутация:
    9
    Оффлайн
    Согласен. Посмотрел. На первом ходу скорость плавала от 14 до 28 кнод/с. Вероятно это говорит о том, что видяха успевала перегреться уже на первом ходе. Иными причинами объяснить столь большую разницу сложно. Но насколько перегрев замедлял работу сложно понять, т.к. время хода обычно было одинаковое, порядка минуты.
  20. Polarity Новичок

    • Новичок
    Рег.:
    23.04.2018
    Сообщения:
    77
    Симпатии:
    17
    Репутация:
    0
    Оффлайн
    Я тестил Lc0 на 8x1080. Полностью загрузить мне удалось 5 видеокарт одновременно, а дальше идёт даже небольшое падение производительности. Я совсем уж детально в коде не разбирался, но на мой взгляд там действительно понатыкано как-то слишком много блокировок и возможно не совсем оптимальным образом. Мне кажется, в DeepMind тоже столкнулись с этой проблемой. Поэтому они использовали всего лишь 4TPU, т. к. поняли, что дальше добалять их бессмысленно.
    Надо помнить, что скорость расчёта ещё очень сильно зависит от текущей позиции. Как правило, скорость расчёта максимальна в самом начале игры и значительно проседает где-то в середине, т. к. доступно не так много "любопытных" ходов для нейронки.
    Скорость расчёта ещё зависела от версии нейросети.
    Сила игры кажется не сильно зависела от количества ресурсов, начиная с некоторого момента. В дискорде даже высказывались мнения, а нужны ли все эти 80k NPS, которые выдавал движок A0.
    Rom, Undying и Mustitz нравится это.
  21. svoitsl Учаcтник

    • Участник
    Рег.:
    05.01.2018
    Сообщения:
    157
    Симпатии:
    28
    Репутация:
    1
    Оффлайн
    Для обучения они вполне успешно загрузили 5000 TPU, вряд ли для игры было уж так трудно загрузить 5
  22. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Для обучения требуется множество независимых друг от друга партий. У всех партий по 800 nodes per move. То есть, на одном TPU играется, скажем, 100 параллельных партий одновременно, по 800 npm каждая. Эти партии не взаимодействуют друг с другом. Так можно распараллеливать сколько угодно, хоть на миллион TPU. Потому что взаимодействие между TPU не требуется.

    В то время как в турнирном режиме мы играем всего лишь одну партию, скажем, по 80000 npm. Поэтому потоки на ядрах/видеокартах должны помогать друг другу. Обмениваться информацией. Для последовательных алгоритмов, таких как альфа-бета или MCTS, это очень непростая задача. Для альфа-беты обычных движках эту проблему недавно решили (там сейчас почти линейное масштабирование по ядрам), а вот для MCTS нейросетевых движков по-видимому пока нет. Может даже и не пытались ещё.
  23. Sergey1983 Учаcтник

    • Участник
    Рег.:
    03.04.2018
    Сообщения:
    126
    Симпатии:
    14
    Репутация:
    1
    Оффлайн
    Для игры нейронки достаточно высокой размерности вполне возможно удалось бы расспараллелить, так как насколько я себе представляю там параллельно считается большее число преобразований фурье которые сами по себе хорошо расспараллельливаються, другое дело что возможно они не хотели отпугивать потенциальных клиентов получившимися аппаратными требованиями технологии ИМХО.
  24. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Параллельно там считается умножение. Это основная операция. Перемножаются трехмерные матрицы. То есть значения в ячейках одной трехмерной таблицы умножаются на соответствующие им значения в ячейках другой таблицы. Понятно, что это легко можно сделать параллельно.

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

    Чтобы сгладить проблему сейчас используется такой трюк, как оценка авансом сразу большого количества позиций одним пакетом в 256 штук. В надежде, что следующая позиция окажется среди них. Но такой подход работает только до определенного предела. И опять же с таким пакетом должна (и может) справляться одна видеокарта. Так что проблема последовательного алгоритма не решается.

    Может, конечно существует простое решение или всё решится как-то само собой, но пока о чем-либо подобном я не слышал.
    svoitsl нравится это.
  25. pavelgttfj8 Учаcтник

    • Участник
    Рег.:
    07.12.2017
    Сообщения:
    150
    Симпатии:
    48
    Репутация:
    2
    Оффлайн
    Где почитать про это?
  26. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Я могу кратко рассказать, подробности по ссылкам ниже.

    Проблема распараллеливания альфа-беты существует уже сорок лет - с тех пор как в широкий обиход вошли многопроцессорные системы.
    https://www.chessprogramming.org/Parallel_Search

    По сути, существуют два подхода к распараллеливанию в обычных движках.
    - Либо использовать почти независимые потоки, каждый со своим деревом перебора, а обмен информацией среди них производить через общую хэш-таблицу (Shared Hash Table). Простой, дешевый в разработке, но неэффективный подход. Нормально работает обычно не более чем на 2-х потоках. Номинально, суммарная скорость потоков большая, но прибавки к силе почти нет.
    - Либо использовать фактически единое дерево перебора, где мастер-поток начинает перебор, расщепляет дерево перебора на отдельные группы, а остальные потоки ждут от него заданий в порядке очереди (Alpha-Beta Splitting). Подход неплохо работает до 8-ми ядер, но постепенно проблема обеспечения работой младших потоков становится всё более и более серьёзной. Младшие потоки ждут и общая скорость падает. Кроме того, подход сложен в реализации.

    До 2015 года наиболее популярным методом был YBW(C), реализующий второй подход. Но с недавних пор, практический все ведущие движки перешли на метод Lazy SMP. А он реализует первый подход!
    https://www.chessprogramming.org/Lazy_SMP

    До сих пор не совсем понятно, почему метод LazySMP реально работает. Он сохраняет все достоинства первого подхода, но отлично масштабируется на большое число ядер. Многие по прежнему не считают его эффективным и даже называют примитивным. Возможно не у всех он работает достаточно хорошо. Но ведущая тройка движков была вынуждена перейти на него, иначе они проигрывали в TCEC. Для Стокфиша тесты показывают, что по крайней мере до 384-х потоков, метод LazySMP при удвоении ядер дает очень хорошую прибавку в силе, возможно такую же, как и при удвоении времени.
    OrderMage и pavelgttfj8 нравится это.
  27. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    8.926
    Симпатии:
    2.107
    Репутация:
    84
    Адрес:
    Москва
    Оффлайн
    Какие-то взаимоисключающие параграфы. Так "нет прибавки", или "отлично масштабируется"? Или, кроме общей хэш-таблицы, у LazySMP есть ещё какая-то фишка, с которой-то всё и заработало?
  28. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    В этом и заключается вся парадоксальность момента, которую я хотел подчеркнуть. Раньше не работало, а сейчас заработало :). А почему, никто толком не знает. Авторы Стокфиша даже удостоились отповеди от Роберта Хьятта, когда захотели реализовать Lazy SMP. А уж он то на распараллеливании собаку съел:
    by bob » Wed Sep 09, 2015 5:46 am
    http://www.talkchess.com/forum3/viewtopic.php?t=57572#p640349

    Фишки есть, но кажется не у всех они работают. Главная проблема - как обеспечить, чтобы каждый поток считал разное дерево:
    by Edsel Apostol » Wed Aug 22, 2018 1:53 pm
    http://talkchess.com/forum3/viewtopic.php?f=7&t=68278

    Но авторам Стока это удалось:
    by mcostalba » Sat Oct 24, 2015 8:30 pm
    http://www.talkchess.com/forum3/viewtopic.php?f=7&t=58031&start=20#p646031

    Тонкостей я не знаю, но основная фишка метода заключается в том, что вариативность потоков обеспечивается переменной глубиной перебора для каждого потока и независимой сортировкой ходов:
    https://www.chessprogramming.org/Lazy_SMP
    OrderMage и WinPooh нравится это.
  29. nn Учаcтник

    • Участник
    Рег.:
    25.03.2007
    Сообщения:
    743
    Симпатии:
    1.502
    Репутация:
    88
    Нарушения:
    9
    Оффлайн
    Потоки общаются только через хэш. Главный поток в итеративном поиске последовательно считает все глубины по очереди.

    У самой первой версии последующие потоки начинали поиск со все более и более большой начальной глубины, которая вычислялась по какой-то простой формуле, а последующие их итерации были как обычно depth+1.
    Это было достаточно, чтобы появилась существенная прибавка по сравнению с ybwc.
    Потом формула для начальной глубины стала логарифмической.
    Потом формула того, каким потокам что считать, была обобщена с пропуска только начальных глубин, чем по сути является выбор начальной глубины, до пропуска и каких-то последующих глубин. Формула задавалась матрицами явно - какую глубину и для какого потока считать или пропускать. Остановились на half-density matrices (Главный считает все, следующие два пропускают глубины через одну, следующие четыре две глубины считают, две пропускают, и т.д. ). Потом эти матрицы под аргументом упрощения сами начали задаваться формулами, а потом и эти формулы изменились немного, так что там нужно разбираться кто, что и когда считает.

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

    Есть еще простая поддержка NUMA, хотя более сложная (но значительно более сложная) давала какую-то не очень большую прибавку.
    Undying, WinPooh и Rom нравится это.
  30. WinPooh В.М.

    • Команда форума
    Рег.:
    13.02.2006
    Сообщения:
    8.926
    Симпатии:
    2.107
    Репутация:
    84
    Адрес:
    Москва
    Оффлайн
    Ходы слишком разные по стоимости? Одному из потоков достанется ход, проигрывающий ферзя, он быстро поймёт, что там все плохо, и закончит работу, будет простаивать. Или выполнять бесполезные вычисления.
    Хотя алгоритмы типа "младшего брата" что-то такое и делали.
  31. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Вроде бы кто-то пробовал расщепление в корне. Многие пробуют метод ABDADA, который отличается тем, что вешает табличку "занято" на исследуемые в текущий момент узлы. Но для Стока и, насколько мне известно, остальных ведущих движков, оказалось правильным по минимуму ограничивать потоки в их возможностях (кроме хэша).
  32. Mustitz Заслуженный

    • Заслуженный
    • Участник
    Рег.:
    30.09.2006
    Сообщения:
    2.930
    Симпатии:
    366
    Репутация:
    21
    Адрес:
    Киев
    Оффлайн
    AlphaGo прекрасно работал на гигантском кластере: для работы AlphaGo использовались 1920 процессоров и 280 графических процессоров, работающих в распределённой сети. Вообще, распараллелить MCTS вообще не проблема (ИМХО). Неужели тяжело выбрать вместой одной позиции сразу 1000 кандидатов для симуляции? Преимущество MCTS перед Alpha-Beta как раз в том, что позволяет эффективно строить такие кластеры. Один сервер раздаёт позиции для симуляций, получает тексты партий и аккумулирует статистику. Остальные заняты независимыми симуляциями. Нам не надо иметь общий многогигабайтный хеш позиций и работать с ним.
  33. Jadn Заслуженный

    • Заслуженный
    • Участник
    Рег.:
    10.05.2006
    Сообщения:
    3.018
    Симпатии:
    933
    Репутация:
    36
    Оффлайн
    Интересно, я не знал, что AB научились нормально масштабировать. Тогда вопрос, почему авторы Лилы решили спаривать нейросети с MCTS? Потому, что в Го хорошо получилось?
  34. sovaz1997 Учаcтник

    • Участник
    Рег.:
    30.08.2016
    Сообщения:
    598
    Симпатии:
    95
    Репутация:
    1
    Оффлайн
    Потому, что Alpha Zero показала хорошие результаты в разных играх, в т. ч. и шахматах, думаю
  35. Rom Учаcтник

    • Участник
    Рег.:
    12.02.2012
    Сообщения:
    546
    Симпатии:
    201
    Репутация:
    21
    Оффлайн
    Сейчас авторы Лилы поставили себе задачу повторить результат DeepMind, а улучшениями займутся потом. В том числе и потому, что при использовании других методов хорошие результаты никто не гарантирует.

Поделиться этой страницей