На чёрных лебедей, наверное, действительно можно забить, а вот, например, на новое слово в тексте — вряд ли. Т.е. если даже у вас есть архив половины интернета, то мы всё равно верим, что во второй половине есть слова, которые мы никогда до этого не видели. И вот эта вера переносит нас от частотного в байесовский подход и заставляет добавлять как минимум +1 ко всем вариантам (а как максимум, предполагать априорное бета распределение для параметров).
В грамотно построенных вычислительных библиотеках ядро написано на C/Fortran.
Всё хорошо, пока вы пользуетесь готовыми библиотеками. А вот когда дело доходит до написания своих и приходиться лезть в этот самый C (про Fortran молчу), начинаешь задумываться о скорости своего основного языка :)
Там кстати можно бинарики собирать уже без внешних зависимостей?
Можно (см., например, BuildExectable.jl), равно как и можно подключать в качестве динамической библиотеки. Правда я до сих пор не понимаю, чем хороши бинарники без внешних зависимостей. Поделитесь, если не секрет.
Честно говоря, после Scala и Rust я довольно скептически отношусь к REPL-ам в статически-типизированных языках. В Scala, например, невозможно перезагрузить класс из пакета (в то время как в Clojure, который на той же платформе, но динамический, это делается супер гибко). Хотя возможно, что мне просто не везёт и кто-нибудь меня переубедить.
Думаю, начинать сравнение D/Phobos и Python/NumPy нужно не со скорости, а с вариантов использования. В отличие от D, Python — язык динамический и поддерживающий полностью интерактивную разработку в REPL. В Python вы можете визуализировать свои данные, попробовать статистическую модель или протестировать новый визуальный фильтр прямо на лету, не закрывая сессию и не пересоздавая данные, что практически невозможно в компилируемом языке без интерактивной консоли. Кроме того, большинство исследователей, на которых во многом ориентирован NumPy, привыкли к динамическим языкам (Matlab, R, Python, etc.), так что вряд ли многие из них захотят копаться в ошибках компиляции в отдалённом куске кода, который в данный момент не собирается и не используется.
Если хотите что-то похожее на Python, но быстрее, посмотрите на Julia. Вот пример вашего кода выше для подсчёта среднего по двумерному массиву:
julia> data = reshape(1:100*10_000, 100, 10_000);
julia> @time mean(data, 1)
0.000580 seconds (17 allocations: 78.813 KB)
julia> @time for i=1:1000 mean(data, 1); end
0.584253 seconds (13.00 k allocations: 76.813 MB, 0.50% gc time) # 584 nanoseconds per iteration
А расскажите поподробней, что из себя представляет программирования под этот Intel Xion Phi. Я правильно понимаю, что на низком уровне просто предоставляютя дополнительные SIMD инструкции, которые обрабатывают уже не 4, а 64 числа в параллели?
И ещё, я так понимаю, что Xion Phi пока производится только для суперкомпьютеров? Т.е. попробовать его у себя дома или, скажем, на сервере в Амазоне пока невозможно?
Давайте начнём с того, что нынче в тренде как раз упомянутые вами сети глубокого обучения, которые и относятся к вычислительным, а никак не к символьным. То, что в некоторых из них для решения частной задачи используетя символьное дифференциирование, никак не переносит эти сети в класс символьных методов, и на Prolog их никто не переписывает.
В остальном вы сказали всё то же, что и я: да, понятия интеллекта и интеллектуальной задачи довольно размыты, и да, таких задач много, языков для их решения тоже много, и ни один из них не даёт "основу прочнее, чем у других языков" для решения всех этих задач.
Ничего не имею против Prolog или вашей статьи (спасибо, кстати, она прояснила некоторые вещи), но вот это:
Пролог в чистом виде не решает всех проблем с интеллектуальными задачами, но он дает основу для их решения. И эта основа прочнее и надежнее, чем у других языков искусственного интеллекта.
всё-таки ваше мнение.Задачи искуственного интеллекта — это очень размытое понятие, но в последние годы оно в основном упоминается в контексте:
1. Машинного обучения
2. Интеллектуальных агентов (по сути то же машинное обучение, но с ответной реакцией)
И вот здесь язык, который даёт самую надёжную основу для решения таких задач, — это математика. В основном, линейная алгебра, статистика и немного мат. анализ. А от языка программирования требуется удобная передача математических методов на вычислительную машину. И вот здесь, насколько мне известно, Prolog-у нечего предложить, по крайней мере не на том уровне, на котором предлагают Python, Matlab, Julia или даже Scala.
Ого, на пороге 2016 года получить ответ на коммнетарий 2011-ого — это почти что машина времени.
Думаю, смысл SICP я всё-таки понял, а вот вы смысл моего комментария, судя по всему, нет. Понятно, что ради академического интереса из любого Лиспа можно сделать язык с вообще любым желаемым набором фич. Но на практике, если вам нужно решить реальную задачу, вы будете пользоваться библиотеками написанными в некотором стиле и подчиняться правилам этого стиля. Если есть веб-сервер, который вам идеально подходит, но хранит в себе состояние и тем самым ломает чистые функции, то на практике вы откажетесь от чистых функций, а не будете переписывать сервер с нуля в функциональном стиле.
В общем, давайте не заморачиваться, а лучше пить шампанское и планировать следущий год ;)
Вроде про опыт и мнение в комментарии ничего не было, я прочитал это как критику статьи в первую очередь. И критика вполне справедливая, т.к. причинно-следственные связи в описании решений похрамывают. Да, действительно, в Scala есть проблема многообразия стилей и подходов, и вопрос не только в читабельности, но и в банальной совместимости библиотек. Но решается это банальным введением конвенций, что гораздо проще, чем изучение нового языка и переписывание существующей кодовой базы.
Что ещё более нелогично, так это то, что Scala всё ещё осталась в инструментарии этой компании. Т.е. если раньше было 2 стиля программирования на Scala, то теперь осталось всё те же 2 стиля плюс другой язык. И чего, спрашивается, они этим добились?
Скорее всего, описанная проблема — это только вершина айсберга, и на самом деле были гораздо более веские причины сменить язык. Но о них в статье ничего не сказано, почему она и вызывает недоверие.
Видел, не понравилось. Вернее даже не так, я в нём по итогу так и не разробрался, т.е. документация касающаяся Spark неполна, но то, что я увидел в коде, меня как-то не впечатлило. D4J имеет поддержку CPU, GPU и Spark за счёт другой библиотеки — ND4J, которая вроде как предоставляет универсальные многомерные массивы, способные работать на всех трёх платформах. Вы пишете один раз, а он автомагически начинает работать везде.
Проблема в том, что CPU, GPU и Spark — это ну очень разные платформы. Очень часто, в т.ч. в конкретном случае с RBM, алгоритмы должны специально адаптироваться для каждой платформы. Здесь же я не нашёл ничего такого ни в коде, ни в комментариях. Возможно, я дико ошибаюсь, но, опять же, мне быстрее написать свою реализации RBM на MLlib, чем разбираться в их коде.
Да почему же, ваша задача со сжатием 100 миллионов файлов и перекладыванием в другое место прекрасно решается через Akka Cluster, причём памяти ему нужно будет по максимальному размеру одного файла.
Spark будет вначале всасывать их в ОЗУ с s3, с HDFS, с Луны всеми нодами
Только вот скорость считывания с HDFS будет ограничена исключительно скоростью работы с диском, а вот S3 будет ограничена и диском, и сетью, которая как бы одна на всех.
Впрочем, убеждать вас в чём-то я не собираюсь: у вас принципиально не те задачи и не те объёмы, для которых важна локальность данных. Появлятся те задачи, сами всё прочувствуете.
Во время выполнения DAG Spark, как сами понимаете, не будет скорее всего уже что-то читать из HDFS — если ОЗУ достаточно, он все уже туда втянет и будет тасовать. Иначе смысл использовать Spark без размещения данных в ОЗУ нод кластера.
Прелесть абстракции RDD как раз в том, что это ленивая коллекция данных, т.е. данные будут читаться с диска только по мере надобности. Это тоже чертовски важный аспект, потому что если у вас 20Тб данных на диске, но вам нужно найти только 10 записей, то в памяти в любой момент времени будет не больше этих самых 10 записей.
Когда положили данные на ноды со Spark — первая часть стала быстрее, а вторая — медленнее на M часов.
На ноды со Spark — это просто на локальный диск? Если да, то скорее всего вы не дали шедулеру самому распределить работу между нодами, вот и получилось, что некоторые справлялись быстрее нужного, а другие отставали и тормозили весь процесс.
сейчас над нашими 150ГБ и вашими 500ГБ смеется конечно Google и Facebook
500Гб — это ежедневный прирост свежих данных. А алгоритмы могут гоняться и за 1, и за 7 и за 30 дней. Добавьте к этому, что RAM-а у нас всего 2Tb, и становится совсем не смешно. Вот в такой ситуации и приходится думать про локальность, избирательное кеширование и прочие оптимизации.
«Map» step: Each worker node applies the «map()» function to the local data, and writes the output to a temporary storage.
Про пункт 3.4 пейпера, который так и называется — Locality — вы уже сами написали. Обратите внимание, что алгоритм всегда пытается размещать воркеров на тех машинах, где есть реплика данных (т.е. вариант, когда они на разных машинах, даже не рассматривается), и только если это невозможно из-за загруженности машин, обработка запускается в другом месте. На практике 95-100% работы выполняется локально.
Если вам мало этого пунтка в пейпере, обратите внимание на схему, где явно указаны read и remote read. Да и если вчитаться, думаю, будет ещё много упоминаний про это.
Зачем читать биографию Дуга Каттинга — не знаю, он не только Хадупом отличился.
Вообще, необходимость локальности становится очевидной, когда начинаете работать с действительно большими данными. В одной из последних задач нам нужно было выкачивать 0.5Tb данных из S3 и обрабатывать их на Spark. Выкачивание и складывание на HDFS занимало час, обработка (вместе с чтением из HDFS) — 40 минут. Вот такая математика.
Deep learning — это именно нейронки по определению, т.к. «deep» относится именно к сетевым структурам, а всё, что сеть, можно назвать нейронкой (даже если вся суть взята из других видов сетей).
Другой вопрос, что есть representation learning — автокодировщики и RBM, основные составные блоки глубоких сетей. Вот их можно использовать и вне контекста нейронок, например, для рекоммендательных движков или уменьшения размерности.
Всё хорошо, пока вы пользуетесь готовыми библиотеками. А вот когда дело доходит до написания своих и приходиться лезть в этот самый C (про Fortran молчу), начинаешь задумываться о скорости своего основного языка :)
Можно (см., например, BuildExectable.jl), равно как и можно подключать в качестве динамической библиотеки. Правда я до сих пор не понимаю, чем хороши бинарники без внешних зависимостей. Поделитесь, если не секрет.
Честно говоря, после Scala и Rust я довольно скептически отношусь к REPL-ам в статически-типизированных языках. В Scala, например, невозможно перезагрузить класс из пакета (в то время как в Clojure, который на той же платформе, но динамический, это делается супер гибко). Хотя возможно, что мне просто не везёт и кто-нибудь меня переубедить.
Если хотите что-то похожее на Python, но быстрее, посмотрите на Julia. Вот пример вашего кода выше для подсчёта среднего по двумерному массиву:
И ещё, я так понимаю, что Xion Phi пока производится только для суперкомпьютеров? Т.е. попробовать его у себя дома или, скажем, на сервере в Амазоне пока невозможно?
В остальном вы сказали всё то же, что и я: да, понятия интеллекта и интеллектуальной задачи довольно размыты, и да, таких задач много, языков для их решения тоже много, и ни один из них не даёт "основу прочнее, чем у других языков" для решения всех этих задач.
всё-таки ваше мнение.Задачи искуственного интеллекта — это очень размытое понятие, но в последние годы оно в основном упоминается в контексте:
1. Машинного обучения
2. Интеллектуальных агентов (по сути то же машинное обучение, но с ответной реакцией)
И вот здесь язык, который даёт самую надёжную основу для решения таких задач, — это математика. В основном, линейная алгебра, статистика и немного мат. анализ. А от языка программирования требуется удобная передача математических методов на вычислительную машину. И вот здесь, насколько мне известно, Prolog-у нечего предложить, по крайней мере не на том уровне, на котором предлагают Python, Matlab, Julia или даже Scala.
Думаю, смысл SICP я всё-таки понял, а вот вы смысл моего комментария, судя по всему, нет. Понятно, что ради академического интереса из любого Лиспа можно сделать язык с вообще любым желаемым набором фич. Но на практике, если вам нужно решить реальную задачу, вы будете пользоваться библиотеками написанными в некотором стиле и подчиняться правилам этого стиля. Если есть веб-сервер, который вам идеально подходит, но хранит в себе состояние и тем самым ломает чистые функции, то на практике вы откажетесь от чистых функций, а не будете переписывать сервер с нуля в функциональном стиле.
В общем, давайте не заморачиваться, а лучше пить шампанское и планировать следущий год ;)
Что ещё более нелогично, так это то, что Scala всё ещё осталась в инструментарии этой компании. Т.е. если раньше было 2 стиля программирования на Scala, то теперь осталось всё те же 2 стиля плюс другой язык. И чего, спрашивается, они этим добились?
Скорее всего, описанная проблема — это только вершина айсберга, и на самом деле были гораздо более веские причины сменить язык. Но о них в статье ничего не сказано, почему она и вызывает недоверие.
Проблема в том, что CPU, GPU и Spark — это ну очень разные платформы. Очень часто, в т.ч. в конкретном случае с RBM, алгоритмы должны специально адаптироваться для каждой платформы. Здесь же я не нашёл ничего такого ни в коде, ни в комментариях. Возможно, я дико ошибаюсь, но, опять же, мне быстрее написать свою реализации RBM на MLlib, чем разбираться в их коде.
Да почему же, ваша задача со сжатием 100 миллионов файлов и перекладыванием в другое место прекрасно решается через Akka Cluster, причём памяти ему нужно будет по максимальному размеру одного файла.
Только вот скорость считывания с HDFS будет ограничена исключительно скоростью работы с диском, а вот S3 будет ограничена и диском, и сетью, которая как бы одна на всех.
Впрочем, убеждать вас в чём-то я не собираюсь: у вас принципиально не те задачи и не те объёмы, для которых важна локальность данных. Появлятся те задачи, сами всё прочувствуете.
Прелесть абстракции RDD как раз в том, что это ленивая коллекция данных, т.е. данные будут читаться с диска только по мере надобности. Это тоже чертовски важный аспект, потому что если у вас 20Тб данных на диске, но вам нужно найти только 10 записей, то в памяти в любой момент времени будет не больше этих самых 10 записей.
На ноды со Spark — это просто на локальный диск? Если да, то скорее всего вы не дали шедулеру самому распределить работу между нодами, вот и получилось, что некоторые справлялись быстрее нужного, а другие отставали и тормозили весь процесс.
500Гб — это ежедневный прирост свежих данных. А алгоритмы могут гоняться и за 1, и за 7 и за 30 дней. Добавьте к этому, что RAM-а у нас всего 2Tb, и становится совсем не смешно. Вот в такой ситуации и приходится думать про локальность, избирательное кеширование и прочие оптимизации.
Про пункт 3.4 пейпера, который так и называется — Locality — вы уже сами написали. Обратите внимание, что алгоритм всегда пытается размещать воркеров на тех машинах, где есть реплика данных (т.е. вариант, когда они на разных машинах, даже не рассматривается), и только если это невозможно из-за загруженности машин, обработка запускается в другом месте. На практике 95-100% работы выполняется локально.
Если вам мало этого пунтка в пейпере, обратите внимание на схему, где явно указаны read и remote read. Да и если вчитаться, думаю, будет ещё много упоминаний про это.
Зачем читать биографию Дуга Каттинга — не знаю, он не только Хадупом отличился.
Вообще, необходимость локальности становится очевидной, когда начинаете работать с действительно большими данными. В одной из последних задач нам нужно было выкачивать 0.5Tb данных из S3 и обрабатывать их на Spark. Выкачивание и складывание на HDFS занимало час, обработка (вместе с чтением из HDFS) — 40 минут. Вот такая математика.
Другой вопрос, что есть representation learning — автокодировщики и RBM, основные составные блоки глубоких сетей. Вот их можно использовать и вне контекста нейронок, например, для рекоммендательных движков или уменьшения размерности.