Как стать автором
Обновить
204.99
Wunder Fund
Мы занимаемся высокочастотной торговлей на бирже
Сначала показывать

16-, 8- и 4-битные форматы чисел с плавающей запятой

Уровень сложности Средний
Время на прочтение 15 мин
Количество просмотров 11K

Уже лет 50, со времён выхода первого издания «Языка программирования Си» Кернигана и Ритчи, известно, что «числа с плавающей запятой» одинарной точности имеют размер 32 бита, а числа двойной точности — 64 бита. Существуют ещё и 80-битные числа расширенной точности типа «long double». Эти типы данных покрывали почти все нужды обработки вещественных чисел. Но в последние несколько лет, с наступлением эпохи больших нейросетевых моделей, у разработчиков появилась потребность в типах данных, которые не «больше», а «меньше» существующих, потребность в том, чтобы как можно сильнее «сжать» типы данных, представляющие числа с плавающей запятой.

Я, честно говоря, был удивлён, когда узнал о существовании 4-битного формата для представления чисел с плавающей запятой. Да как такое вообще возможно? Лучший способ узнать об этом — самостоятельно поработать с такими числами. Сейчас мы исследуем самые популярные форматы чисел с плавающей запятой, создадим с использованием некоторых из них простую нейронную сеть и понаблюдаем за тем, как она работает.

Читать далее
Всего голосов 108: ↑107 и ↓1 +106
Комментарии 79

Две мощных возможности Python, упрощающие код и улучшающие его читабельность

Уровень сложности Простой
Время на прочтение 10 мин
Количество просмотров 23K

Улучшите качество кода, украсив его оператором match и срезами объектов.

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

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

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

Читать далее
Всего голосов 30: ↑23 и ↓7 +16
Комментарии 27

Исследование режима Copy-on-Write в pandas. Часть 3

Уровень сложности Средний
Время на прочтение 5 мин
Количество просмотров 1.6K

Появление в библиотеке pandas режима Copy‑on‑Write (CoW, копирование при записи) — это изменение, нарушающее обратную совместимость, которое окажет некоторое воздействие на существующий код, использующий pandas. Мы разберёмся с тем, как адаптировать код к новым реалиям, сделать так, чтобы он работал бы без ошибок тогда, когда режим CoW будет включён по умолчанию. Сейчас сделать это планируется в версии pandas 3.0, выход которой ожидается в апреле 2024 года. В первом материале из этой серии мы разбирались с особенностями поведения CoW, во втором — говорили об оптимизации производительности, имеющей отношение к новому режиму работы pandas.

Мы планируем добавить в систему «тревожный режим», в котором она будет выдавать предупреждения при выполнении любой операции, поведение которой меняется при включении CoW. Эти предупреждения будут привлекать к себе очень много внимания пользователей, поэтому к возможности их появления стоит относиться с осторожностью. В этом материале рассматриваются некоторые типичные проблемы кода и то, как его можно адаптировать для того чтобы его поведение не изменилось бы после включения CoW.

Читать далее
Всего голосов 14: ↑14 и ↓0 +14
Комментарии 0

Исследование режима Copy-on-Write в pandas. Часть 2

Уровень сложности Средний
Время на прочтение 6 мин
Количество просмотров 2.1K

В первом материале из этой серии была объяснена работа механизма Copy‑on‑Write (CoW, копирование при записи). Там были упомянуты некоторые ситуации, в которых при выполнении кода осуществляется копирование данных. В этой статье речь пойдёт об оптимизации, направленной на то, чтобы копирование не ухудшило бы средних показателей скорости работы кода.

Мы используем подход, применяемый внутри pandas для того, чтобы избежать копирования всего объекта DataFrame в тех случаях, когда это не нужно. Этот подход позволяет повысить производительность системы.

Читать далее
Всего голосов 17: ↑17 и ↓0 +17
Комментарии 1

Исследование режима Copy-on-Write в pandas. Часть 1

Уровень сложности Средний
Время на прочтение 10 мин
Количество просмотров 4.4K

Библиотека pandas 2.0 вышла в начале апреля, в ней появилось много улучшений нового режима Copy‑on‑Write (CoW, копирование при записи). Ожидается, что в pandas 3.0 режим CoW будет использоваться по умолчанию. Сейчас полный переход на копирование при записи запланирован на апрель 2024 года. У разработчиков библиотеки нет планов поддержки некоего «режима совместимости» или режима, в котором CoW не применяется.

Эта серия публикаций посвящена рассказу о том, как работают внутренние механизмы CoW в pandas. Она призвана помочь пользователям библиотеки понять, что происходит при выполнении кода, узнать о том, как эффективно пользоваться копированием при записи, и о том, как адаптировать свой код под новые возможности pandas. Здесь будут приведены примеры того, как использовать данный механизм для того чтобы добиться от системы самого высокого уровня производительности. Здесь же будет рассмотрено и несколько антипаттернов, использование которых в программах ведёт к появлению в них ненужных «узких мест». Пару месяцев назад я написал небольшой вводный материал по Copy‑on‑Write в pandas.

Читать далее
Всего голосов 10: ↑10 и ↓0 +10
Комментарии 1

«Да» — расписаниям, «нет» — спискам дел

Уровень сложности Простой
Время на прочтение 14 мин
Количество просмотров 28K

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

Однако же, жизни многих людей работают на сбойных операционных системах. Они называются «списками дел». Встречался вам кто‑нибудь, кто управляет временем, используя списки дел, и реально завершает все запланированные на день задачи? Я таких людей не видел.

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

Читать далее
Всего голосов 22: ↑20 и ↓2 +18
Комментарии 29

От теории к практике: создаём веб-приложение для решения задачи коммивояжёра

Уровень сложности Средний
Время на прочтение 14 мин
Количество просмотров 5K

В таких сферах, как исследование операций (Operations Research) и наука о данных (Data Science) чрезвычайно актуально сближение теории и её практического применения в виде программных проектов. Теоретические выкладки формируют базу программ для оптимизации чего‑либо, так как теория даёт средства для решения разнообразных задач. Но очень важно помнить и о том, что подобные программы должны быть доступны конечному пользователю, что с ними должно быть удобно работать.

Задача коммивояжёра (Traveling Salesman Problem, TSP) — это, без сомнения, та самая задача комбинаторной оптимизации, которая изучена лучше всего (Rego, C., Gamboa, D., Glover, F., & Osterman, C., 2011. Traveling salesman problem heuristics: Leading methods, implementations and latest advances. European Journal of Operational Research, 211(3), 427–441). Её легко описать (по крайней мере — на словах), её можно использовать для того чтобы продемонстрировать некоторые из возможных компонентов API современной программы по построению маршрутов. В результате я просто не мог подобрать ничего лучше этой задачи в качестве основы для примера, который разобран в этой статье.

Здесь вы узнаете о том, как использовать Python‑библиотеку Streamlit для создания веб‑приложения, которое позволяет решать задачу коммивояжёра с использованием входных данных, предоставленных пользователем. Так как нас интересует создание приложения, пригодного для решения реальных задач, мы, анализируя пути перемещения между некими географическими точками, будем интересоваться не только евклидовым расстоянием между ними, но и другими характеристиками путей. В частности, наша программа, используя координаты точек, должна уметь получать данные о том, какое расстояние по автомобильным дорогам нужно преодолеть для перемещения между ними. Эти данные должны учитываться при выполнении оптимизации. Для этого мы воспользуемся API OpenStreetMap.

Если вы хотите лучше разобраться в теоретических аспектах числовой оптимизации — вам, возможно, интересно будет почитать мои статьи о линейном программировании и о задаче маршрутизации транспорта (это — обобщение задачи коммивояжёра).

Готовы поработать? Взгляните на то, что у нас должно в итоге получиться…

Читать далее
Всего голосов 17: ↑17 и ↓0 +17
Комментарии 2

Чем на самом деле занимается Chief Technical Officer?

Уровень сложности Простой
Время на прочтение 18 мин
Количество просмотров 11K

В 2017 году я впервые почувствовал себя в роли CTO (Chief Technical Officer, технический директор). Я присоединился к маленькому стартапу в роли разработчика‑сеньора, и не успел опомниться, как оказалось, что я держу в руках бразды правления технической командой. Если сказать кому о том, что я занимаю пост технического директора, прозвучало бы это впечатляюще, но на самом деле моя должность больше соответствовала роли технического руководителя проекта. Я трудился в маленькой компании, в состав которой входило человек десять сотрудников, и плотно занимался разработкой продукта этой компании. Мои дни были наполнены программированием, отладкой и постоянной борьбой с новыми багами и проблемами клиентов. Я, кроме того, был ответственным за то, чтобы наша команда выполняла бы обязательства перед инвесторами и клиентами. Это было не только время непростых задач, но и время мощного обучения, и время профессионального роста.

И ещё — то было время постоянного стресса. Но это — уже совсем другая история.

Перенесёмся в наши дни. Сегодня я — сооснователь цифрового агентства, которое находится в Швейцарии. В нём я занимаю должность CTO. Мы одновременно работаем над несколькими проектами, задействуя в каждом из них универсальные команды. Наше агентство, со времён его создания, немного подросло. Теперь в нём работает почти 50 человек. Эволюционировала и та роль, которую я в нём играю. Я больше не занимаюсь только программированием и отладкой. Теперь я управляю ресурсами, занимаюсь планированием, принимаю стратегические решения. Сейчас передо мной стоят другие непростые задачи. Но я, как и раньше, прямо‑таки наслаждаюсь, решая разного рода проблемы, и понимая, что я — тот, кто формирует техническое видение компании.

Читать далее
Всего голосов 20: ↑18 и ↓2 +16
Комментарии 1

Minetester: полностью открытое окружение для обучения с подкреплением, построенное на основе Minetest

Уровень сложности Средний
Время на прочтение 17 мин
Количество просмотров 2.6K

В последние несколько месяцев наблюдаются значительные успехи в разработке языковых моделей, особенно — в сфере частного бизнеса. В прошлом году вышло несколько подобных проектов, основанных на Minecraft. В частности — речь идёт о фреймворке MineDojo, который представляет собой огромный симулятор, а так же — о системах, позволяющих ИИ‑агентам обучаться игре в Minecraft с помощью VPT (Video PreTraining). Похожие проекты появились и в этом году. Среди них — системы, в которых используется SOTA LLM, модель STEVE-1, Minecraft‑агент Voyager, фреймворк GITM.

Базой всех этих разработок является игра Minecraft. В них, кроме того, обычно используется окружение MineRL. Мы, для удовлетворения наших исследовательских потребностей, занимаемся работой над другим стеком инструментов, который основан на воксельном движке Minetest.

Читать далее
Всего голосов 15: ↑15 и ↓0 +15
Комментарии 1

Революция в оптимизаторах: DeepMind использует большие языковые модели в роли интеллектуальных оптимизаторов

Уровень сложности Простой
Время на прочтение 3 мин
Количество просмотров 4.1K

В новой публикации «Large Language Models as Optimizers» (Большие языковые модели в роли оптимизаторов) команда исследователей Google DeepMind представила инновационный метод оптимизации, названный «оптимизация через промпты» (Optimization by PROmpting, OPRO). При применении этого метода в роли оптимизаторов используются большие языковые модели (Large Language Model, LLM). С его помощью можно генерировать решения, зависящие от описаний задач оптимизации, выполненных на естественном языке.

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

Читать далее
Всего голосов 16: ↑16 и ↓0 +16
Комментарии 4

Реверс-инжиниринг промптов for fun and (no) profit

Уровень сложности Простой
Время на прочтение 15 мин
Количество просмотров 2.1K

Этот материал посвящён взлому промптов Notion AI, семи методикам реверс‑инжиниринга промптов и рассказу о том, почему все ошибаются в своих мнениях о промпт‑инъекциях (prompt injection).

Вчера я получил доступ к публичной альфа‑версии Notion AI. У меня ушло 2 часа на то, чтобы, пользуясь промпт‑инъекциями, раздобыть полные тексты внутренних промптов, применяемых для реализации каждой из возможностей Notion AI.

Сегодня я публикую тексты этих промптов, но делаю это не потому, что я — человек безответственный; я отстаиваю точку зрения, в соответствии с которой в этом нет ничего страшного. И я воздаю должное команде Notion, которая так хорошо интегрировала возможности искусственного интеллекта в свой продукт.

Мне, кроме того, пришлось разработать и использовать кое‑какие новые техники приблизительного определения исходных текстов промптов. Я подумал, что было бы интересно представить их вам — моим замечательным читателям.

Читать далее
Всего голосов 19: ↑19 и ↓0 +19
Комментарии 3

Архетипы программных архитекторов. Часть 2

Уровень сложности Простой
Время на прочтение 9 мин
Количество просмотров 4.6K

Привет Хабр! Сегодня публикуем вторую часть материала об архетипах программных архитекторов. Если пропустили, то вот первая часть.

Читать далее
Всего голосов 16: ↑16 и ↓0 +16
Комментарии 0

Архетипы программных архитекторов. Часть 1

Уровень сложности Простой
Время на прочтение 13 мин
Количество просмотров 9.2K

Что такое архетип? Это — образец набора вариантов поведения или поведенческих сценариев, типичных для определённой роли. Уилл Ларсон, который сейчас занимает должность главного технического директора в Carta, определил четыре архетипа для должности «ведущий инженер‑программист» (Staff Engineer). Это — «техлид» (Tech Lead), «архитектор» (Architect), «решатель задач» (Solver) и «незаменимый помощник» (Right Hand).

Я работаю над новой книгой, которую планируется опубликовать этой осенью. Она называется «The Software Engineerʼs Guidebook». Когда я писал в ней об архитектуре ПО, меня зацепила идея существования «архетипов» программных архитекторов, которые могут сочетаться друг с другом либо хорошо, либо плохо. Речь идёт о людях, работающих бок о бок друг с другом, вклад каждого из которых в общее дело отличается чем-то особенным. Разбираться с тем, какие архетипы лучше всего описывают коллег — это интересное занятие, которое может привести к ценным открытиям. И вполне возможно, что вы, задумываясь об этом, поймёте, какой из архетипов лучше всего описывает вас самих.

Читать далее
Всего голосов 20: ↑18 и ↓2 +16
Комментарии 8

Что LLM знают о лингвистике? Это зависит от того, какие вопросы им задают

Уровень сложности Средний
Время на прочтение 15 мин
Количество просмотров 3.9K

Развитие больших языковых моделей (Large Language Model, LLM) привело к смене парадигмы в сфере обработки естественного языка (Natural Language Processing, NLP). LLM, обученные на огромных объёмах текста, взятого из интернета, могут осваивать выполнение новых задач, задействуя механизмы контекстного обучения. Это означает, что NLP‑специалисты, «натаскивая» такие модели на решение определённых задач, не занимаются обновлением их параметров. Вместо этого специалисты пишут для LLM промпты, демонстрирующие желаемое поведение моделей и содержащие инструкции или некоторое количество готовых примеров. Эти промпты передают моделям в виде входного контекста (потому это и называют «контекстным обучением»), а модели используют информацию из промптов для формирования ответов на похожие вопросы.

Читать далее
Всего голосов 10: ↑10 и ↓0 +10
Комментарии 0

Brain2Music: как нейроcеть распознает мелодии по МРТ мозга

Уровень сложности Простой
Время на прочтение 3 мин
Количество просмотров 1.9K

Музыка — это универсальный язык, для которого нет границ. Стремительный прогресс больших языковых моделей (Large Language Model, LLM) привёл к тому, что нейроучёные продемонстрировали острый интерес к исследованию представления музыки в человеческом мозгу.

Команда учёных из Google, Осакского университета, NICT и Araya Inc., движимая этим интересом, провела исследование, результаты которого изложены в публикации «Brain2Music: Reconstructing Music from Human Brain Activity». В исследовании используется конвейер обработки данных, названный Brain2Music, в состав которого входит модель MusicLM, реконструирующая музыку, которую слышит человек, на основе его мозговой активности. Система генерирует композиции, которые напоминают исходные музыкальные раздражители. Этот новый метод даёт ценные сведения о взаимоотношениях мозговой активности с когнитивным и чувственным опытом людей.

Учёные сделали следующие основные выводы:

Читать далее
Всего голосов 15: ↑15 и ↓0 +15
Комментарии 2

Протоколы в Python

Уровень сложности Простой
Время на прочтение 8 мин
Количество просмотров 14K

В Python 3.8. появилась новая примечательная возможность — протоколы (protocols). Протоколы — это альтернатива абстрактным базовым классам (abstract base classes, ABC). Они позволяют пользоваться структурной подтипизацией (structural subtyping), то есть — осуществлять проверку совместимости классов исключительно на основе анализа их атрибутов и методов. В этом материале мы поговорим о протоколах в Python и разберём практические примеры работы с ними.

Читать далее
Всего голосов 21: ↑20 и ↓1 +19
Комментарии 4

Качественный набор данных от Microsoft для обучения компактных, но мощных языковых моделей, генерирующих код

Уровень сложности Средний
Время на прочтение 4 мин
Количество просмотров 2.5K

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

Исследовательская команда Microsoft, вдохновлённая этими идеями, провела эксперимент, отчёт о котором — Textbooks Are All You Need — можно найти на arXiv.org. В рамках эксперимента была создана большая языковая модель для генерирования кода, названная phi-1. Обучение этой модели проводилось с использованием специально подготовленного набора данных, качество которого сопоставимо с учебниками по программированию. В результате модель phi-1, при том, что в ней используется всего 1,3 миллиарда параметров, показала результаты, превосходящие то, на что способны самые совершенные большие языковые модели.

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

Читать далее
Всего голосов 13: ↑13 и ↓0 +13
Комментарии 4

Визуализация реальных масштабов проклятия размерности

Уровень сложности Средний
Время на прочтение 11 мин
Количество просмотров 5.7K

Представьте себе набор данных, состоящий из некоторого количества наблюдений. У каждого наблюдения имеется N признаков. Если преобразовать все эти признаки в их числовое представление, то можно будет сказать, что каждое из наблюдений — это точка в N‑мерном пространстве.

Если N — величина небольшая — взаимоотношения между точками будут именно такими, какими их можно представить на интуитивном уровне. Но иногда N достигает огромных значений. Это может произойти, например, когда множество признаков создают посредством прямого кодирования или чего‑то подобного. Для очень больших значений N наблюдения ведут себя так, как если бы они были бы представлены разреженными данными, или так, как если бы расстояния между ними были бы несколько больше, чем можно было бы ожидать.

Это — реальное явление. По мере роста N, при условии, что всё остальное не меняется, объём части N‑мерного пространства, содержащий наблюдения, тоже, в некотором смысле, увеличивается (или, как минимум, увеличивается количество степеней свободы). Увеличиваются и евклидовы расстояния между наблюдениями. Группа точек становится всё более разреженной структурой. Это — геометрическая база для такого понятия, как «проклятие размерности». Подобные изменения в данных влияют на поведение моделей и на приёмы работы, применяемые к наборам данных.

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

Читать далее
Всего голосов 32: ↑32 и ↓0 +32
Комментарии 5

GPT и человеческая психология

Уровень сложности Простой
Время на прочтение 16 мин
Количество просмотров 7.6K

Генеративные текстовые модели, например — ChatGPT и GPT-4, кардинально изменили всё то, что происходит в области искусственного интеллекта (ИИ, AI, Artificial Intelligence).

GPT‑модели (Generative Pre‑trained Transformer, генеративный предобученный трансформер), похоже, донельзя снизили порог входа в сферу ИИ, сделав её доступной даже тем, кто весьма далёк от компьютерных технологий. Любой может просто начать спрашивать модель обо всём на свете и получать пугающе точные ответы.

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

Когда модель не выдаёт правильный ответ — это не значит, что она не в состоянии это сделать. Часто нужно всего лишь изменить предлагаемое ей задание, или «промпт» (prompt, подсказка), таким образом, чтобы направить модель к верному ответу.

Это часто называют «промпт‑инжинирингом» (prompt engineering).

В основе многих приёмов промпт‑инжиниринга лежат попытки сымитировать то, как работает человеческое мышление. Отличные примеры имитации мышления людей — это когда моделям предлагают «подумать вслух» (think aloud ) или говорят: «давай продумаем этот вопрос пошагово» (let's think step by step).

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

Читать далее
Всего голосов 15: ↑13 и ↓2 +11
Комментарии 3

Развлечения с хеш-коллизиями

Уровень сложности Средний
Время на прочтение 9 мин
Количество просмотров 3.5K

Мой друг и коллега по цеху, блоггер Сэм, недавно опубликовал своё третье иллюстрированное руководство, темой которого стало хеширование. Нет острой необходимости читать его руководство перед прочтением моей статьи, но я очень рекомендую вам это сделать. Хотя бы ради того, чтобы посмотреть на восхитительные анимации, от которых невозможно оторваться. Честно — они просто потрясающие. Тут, к сожалению, анимаций вы не найдёте, поэтому насмотритесь на них в той статье, а потом возвращайтесь сюда. Здесь вы сможете немного позабавиться поиском коллизий алгоритма хеширования MurmurHash3.

Сразу хочу отметить, что этот материал я писал исключительно ради развлечения. Ничто из того, что я тут покажу, не предназначено для продакшн-кода. И вот, как всегда, ссылка на GitHub-репозиторий, в котором можно найти код к этой статье.

Идея этого поста возникла после того, как меня попросили помочь с поиском коллизий. Тогда меня охватило непреодолимое желание узнать о том, сколько хешей в секунду я смогу выжать из доступного мне железа. Собственно, тут я расскажу о поиске хеш-коллизий MurmurHash3 на скорости 200 гигахешей в секунду.

Читать далее
Всего голосов 22: ↑19 и ↓3 +16
Комментарии 4

Информация

Сайт
wunderfund.io
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия
Представитель
xopxe