[{"data":1,"prerenderedAt":632},["ShallowReactive",2],{"page:\u002Fru\u002Fposts\u002Fcode_n_shit\u002Ftensorflow_from_source":3,"translations:\u002Fru\u002Fposts\u002Fcode_n_shit\u002Ftensorflow_from_source":631},{"id":4,"title":5,"author":6,"body":7,"date":618,"description":13,"draft":619,"extension":620,"image":621,"listed":622,"meta":623,"navigation":622,"path":624,"seo":625,"stem":626,"tags":627,"theme":6,"toc":622,"__hash__":630},"content_ru\u002Fru\u002Fposts\u002Fcode_n_shit\u002Ftensorflow_from_source.md","Ускоряем TensorFlow сборкой из исходников",null,{"type":8,"value":9,"toc":600},"minimark",[10,14,17,22,28,31,34,38,41,123,131,138,141,144,226,229,331,334,338,341,352,355,360,363,367,370,374,389,394,397,401,404,408,413,425,429,432,522,526,529,542,546,549,555,558,564,567,573,576,580,587,591,594,597],[11,12,13],"p",{},"Как заставить TensorFlow работать на CPU до 7 раз быстрее.",[11,15,16],{},"Или примерно в 3 в моем случае.",[18,19,21],"h2",{"id":20},"мой-кейс","Мой кейс",[23,24,25],"blockquote",{},[11,26,27],{},"Должен заметить что это первая статья связанная с ML(надеюсь будет больше)",[11,29,30],{},"Так уж вышло что в данный момент я работаю над проектом, частью которого является небольшая нейронная сеть. А точнее две: по-больше по-важнее и по-меньше по-необязательнее.\nРечь будет идти в основном о первой.",[11,32,33],{},"В общем-то это известная в узких кругах модель: YOLO\u002Fdarknet, а точнее вторая ее версия. Казалось бы при чем тут Tensorflow?\nА при том, что использую я ее не напрямую(потому что ~~~пошли они~~~ неочевидно как пользоваться при отсутствующей документации), а через форк darkflow, который \"дословно\" переводит darknet в tensorflow понятные штуки.",[18,35,37],{"id":36},"статка","Статка",[11,39,40],{},"Еще до запуска на лептопе(да не стоило) было понятно, что нужно делать сервак, однако я решил попробовать.\nИтак результат на ноутбуке(0)",[42,43,44,87],"table",{},[45,46,47],"thead",{},[48,49,50,55,58,61,68,73,76,78,81,84],"tr",{},[51,52,54],"th",{"align":53},"center","№",[51,56,57],{"align":53},"Dataset size",[51,59,60],{"align":53},"Batch",[51,62,63,64],{"align":53},"t",[65,66,67],"sub",{},"1000",[51,69,63,70],{"align":53},[65,71,72],{},"1",[51,74,75],{"align":53},"CPU Load",[51,77,63],{"align":53},[51,79,80],{"align":53},"CPU",[51,82,83],{"align":53},"RAM",[51,85,86],{"align":53},"OS",[88,89,90],"tbody",{},[48,91,92,96,99,102,105,108,111,114,117,120],{},[93,94,95],"td",{"align":53},"0",[93,97,98],{"align":53},"100",[93,100,101],{"align":53},"16",[93,103,104],{"align":53},"5ч",[93,106,107],{"align":53},"18с",[93,109,110],{"align":53},"100%",[93,112,113],{"align":53},"105°C",[93,115,116],{"align":53},"2 x 2.7GHz",[93,118,119],{"align":53},"8Gb DDR3",[93,121,122],{"align":53},"macOS",[11,124,125,130],{},[126,127,63,128],"b",{},[65,129,67],{}," - Время на 1000 шагов обучения",[11,132,133,137],{},[126,134,63,135],{},[65,136,72],{}," - Время на 1 шаг обучения",[11,139,140],{},"Да, ерунда конечно, но эксперимент есть эксперимент, пришлось потерпеть вечерок шум ноутбука.",[11,142,143],{},"Пробуем сервер(1), результаты:",[42,145,146,174],{},[45,147,148],{},[48,149,150,152,154,156,160,164,166,168,170,172],{},[51,151,54],{"align":53},[51,153,57],{"align":53},[51,155,60],{"align":53},[51,157,63,158],{"align":53},[65,159,67],{},[51,161,63,162],{"align":53},[65,163,72],{},[51,165,75],{"align":53},[51,167,63],{"align":53},[51,169,80],{"align":53},[51,171,83],{"align":53},[51,173,86],{"align":53},[88,175,176,198],{},[48,177,178,180,182,184,186,188,190,192,194,196],{},[93,179,95],{"align":53},[93,181,98],{"align":53},[93,183,101],{"align":53},[93,185,104],{"align":53},[93,187,107],{"align":53},[93,189,110],{"align":53},[93,191,113],{"align":53},[93,193,116],{"align":53},[93,195,119],{"align":53},[93,197,122],{"align":53},[48,199,200,202,204,206,209,212,214,217,220,223],{},[93,201,72],{"align":53},[93,203,98],{"align":53},[93,205,101],{"align":53},[93,207,208],{"align":53},"3ч",[93,210,211],{"align":53},"11с",[93,213,110],{"align":53},[93,215,216],{"align":53},"n\u002Fa",[93,218,219],{"align":53},"8 x 2.3GHz",[93,221,222],{"align":53},"16Gb DDR3",[93,224,225],{"align":53},"Ubuntu",[11,227,228],{},"Прирост конечно есть, но все еще до невозможности медленно. Да еще и куча варнингов, мол можно быстрее если скомпилировать с каким-то AVX и еще кучей библиотек. Штош, пробуем(2):",[42,230,231,259],{},[45,232,233],{},[48,234,235,237,239,241,245,249,251,253,255,257],{},[51,236,54],{"align":53},[51,238,57],{"align":53},[51,240,60],{"align":53},[51,242,63,243],{"align":53},[65,244,67],{},[51,246,63,247],{"align":53},[65,248,72],{},[51,250,75],{"align":53},[51,252,63],{"align":53},[51,254,80],{"align":53},[51,256,83],{"align":53},[51,258,86],{"align":53},[88,260,261,283,305],{},[48,262,263,265,267,269,271,273,275,277,279,281],{},[93,264,95],{"align":53},[93,266,98],{"align":53},[93,268,101],{"align":53},[93,270,104],{"align":53},[93,272,107],{"align":53},[93,274,110],{"align":53},[93,276,113],{"align":53},[93,278,116],{"align":53},[93,280,119],{"align":53},[93,282,122],{"align":53},[48,284,285,287,289,291,293,295,297,299,301,303],{},[93,286,72],{"align":53},[93,288,98],{"align":53},[93,290,101],{"align":53},[93,292,208],{"align":53},[93,294,211],{"align":53},[93,296,110],{"align":53},[93,298,216],{"align":53},[93,300,219],{"align":53},[93,302,222],{"align":53},[93,304,225],{"align":53},[48,306,307,310,312,314,317,320,323,325,327,329],{},[93,308,309],{"align":53},"2",[93,311,98],{"align":53},[93,313,101],{"align":53},[93,315,316],{"align":53},"40м",[93,318,319],{"align":53},"3с",[93,321,322],{"align":53},"80%",[93,324,216],{"align":53},[93,326,219],{"align":53},[93,328,222],{"align":53},[93,330,225],{"align":53},[11,332,333],{},"Что? Прирост производительности в 4 раза? Да еще и виртуалка перестала сыпать предупреждениями об использовании проца на 100%. Магия не иначе. Разбираемся.",[18,335,337],{"id":336},"почему-так","Почему так",[11,339,340],{},"Давай взглянем что я там накомпилировал. Я использовал следующие флаги при сборки Bazelisk-ом:",[342,343,348],"pre",{"className":344,"code":346,"language":347},[345],"language-text","--copt=-mavx --copt=-mavx2 --copt=-mfma\n","text",[349,350,346],"code",{"__ignoreMap":351},"",[11,353,354],{},"За каждым из них скрывается библиотека. Посмотрим поближе что они делают:",[356,357,359],"h3",{"id":358},"avx-и-avx2","AVX и AVX2",[11,361,362],{},"AVX это аббревиатура от Advanced Vector Extensions. Это расширение команд для процессоров x86, которое вкючает в себя кучу различных обновлений в схеме работы с памятью в целом и во время вычислений, определяет новые регистры(или тип того), но самое главное делает работу с векторной(тензорной) ~~~математикой~~~ арифметикой быстрее и проще. А как мы знаем, TensorFlow, неожиданно, работает именно с ней.",[356,364,366],{"id":365},"mfma","mFMA",[11,368,369],{},"Fused Multiply-Add - так же набор инструкций для процессоров x86, упрощающий и ускоряющий работу со сложением-умножением чисел с плавающей запятой.",[356,371,373],{"id":372},"что-нибудь-еще-и-gpu-сюда-же","Что-нибудь еще и GPU сюда же",[11,375,376,377,380,381,384,385,388],{},"Чтобы понять что ставить, сделай ",[349,378,379],{},"cat \u002Fproc\u002Fcpuinfo | grep flags"," и сравни это с тем, что поддерживает Bazel сборка TensorFlow. Или еще лучше просто поставь собранный TensorFlow каким-нибудь ",[349,382,383],{},"pip install tensorflow"," и выполни ",[349,386,387],{},"python -c 'import tensorflow as tf; tf.Session()'"," и tf сам скажет тебе какие инструкции поддерживает твой процессор, но библиотеки не оптимизированы под них.",[23,390,391],{},[11,392,393],{},"Есть легенда, что если поставить TensorFlow через Anaconda(conda), то можно тоже добится неплохого прироста без того, что будет описано дальше в статье, однако лично мне это ощутимого прироста не дало, а варнинги остались на своем месте",[11,395,396],{},"Если у тебя есть GPU - на ноуте или тем более сервере(если так, то не знаю что ты тут забыл, но раз уже забыл, то поделись🙏🏻).",[18,398,400],{"id":399},"эта-установка-заставит-тебя-попотеть","Эта установка заставит тебя попотеть",[11,402,403],{},"Лично у меня, а я себя тупым не считаю, получилось примерно с 5 раза. Почему сейчас объясню.",[356,405,407],{"id":406},"ставим-ненавистный-bazeliskbazel","Ставим ненавистный Bazelisk(Bazel)",[409,410,412],"h4",{"id":411},"ахтунг-бомбеж","Ахтунг: бомбеж",[11,414,415,416,420,421],{},"Я не знаю кто придумал это, но для него есть отдельный котел в аду, ведь человек, или люди, который решил использовать вместо make\u002Fcmake - это, просто-напросто садист.\nНачнем с того, что в зависимости от того, какую версию TF ты ставишь, тебе нужны не просто разные версии TF, а разные версии установщика, а иногда еще и JDK.\nПродолжим это тем, что сборка конфигурируется и скриптом и флагами, и где что и как друг на друга влияет вообще не ясно.\nУстановщик этого установщика существует минимум в трех вариантах и ни один их них не рабочий. В общем вбив в гуглий после 4-ой, неудачной попытки ",[417,418,419],"strong",{},"What the fuck is Bazel?!",", я не был удивлен статьями вроде этой:\n",[422,423],"img",{"alt":351,"src":424},"\u002Fimages\u002Ffckbazel.png",[409,426,428],{"id":427},"за-дело","За дело",[11,430,431],{},"Итак узнаем какую версию bazel нам нужно поставить для нужной нам версии tf и поставим её.",[433,434,435,447,461,475,483,498,504,517],"ol",{},[436,437,438,439,446],"li",{},"Для этого открывай ",[440,441,445],"a",{"href":442,"rel":443},"https:\u002F\u002Fgithub.com\u002Ftensorflow\u002Ftensorflow.git",[444],"nofollow","репозиторий tensorflow"," и переходи в релиз-ветку по тегу.",[436,448,449,450,453,454,457,458],{},"В файле ",[349,451,452],{},"configure.py"," ищем ",[349,455,456],{},"_TF_MIN_BAZEL_VERSION"," и\u002Fили ",[349,459,460],{},"_TF_MAX_BAZEL_VERSION",[436,462,463,466,467,474],{},[417,464,465],{},"ЕСЛИ"," такого файла нет(что обычно бывает в версиях как минимум до 2.0), то идешь ",[417,468,469],{},[440,470,473],{"href":471,"rel":472},"https:\u002F\u002Fwww.tensorflow.org\u002Finstall\u002Fsource#tested_build_configurations",[444],"сюда",", ищешь свою платформу, версию tf и соответствующую версию bazel.",[436,476,477,478],{},"Ищешь нужную версию bazel в релизах на ",[440,479,482],{"href":480,"rel":481},"https:\u002F\u002Fgithub.com\u002Fbazelbuild\u002Fbazel\u002Freleases",[444],"github",[436,484,485,486,489,490,493,494,497],{},"Качаешь ",[349,487,488],{},"wget","-ом ",[349,491,492],{},"bazel-\u003Cчето там>-installer.sh",", а если тоже на Ubuntu, то конечно ",[349,495,496],{},".deb"," пакет",[436,499,500,501],{},"Запускаешь инсталлер один раз так, другой раз с ключем --user, либо просто apt install ",[349,502,503],{},".\u002Fbazel-\u003Csmth>.deb",[436,505,506,507,510,511,514],{},"Проверь установку ",[349,508,509],{},"bazel version"," - он прогрузится и доставит нужные и ненужные зависимости и покажет версию. Убедись что она совпадает с той, которая тебе нужна",[512,513],"br",{},[417,515,516],{},"???",[436,518,519],{},[417,520,521],{},"PROFIT",[356,523,525],{"id":524},"готовимся-к-сборке","Готовимся к сборке",[11,527,528],{},"TF ты уже склонировал, и коли не дурак то сделал checkout на твою ветку. Если нет, то сделай это.",[433,530,531,536],{},[436,532,533],{},[349,534,535],{},"cd tensorflow",[436,537,538,541],{},[349,539,540],{},".\u002Fconfigure"," - Если охота и возможность можно даже проследовать нестандартным путем и наставить всякого, что может еще ускорить tf в дальнейшем. А может и нет. А может и да.",[356,543,545],{"id":544},"собираем","Собираем",[11,547,548],{},"Как я уже писал, я собирал с AVX, AVX2 и mFMA, поэтому для меня команда выглядела так:",[342,550,553],{"className":551,"code":552,"language":347},[345],"bazel build --config=opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-mfpmath=both -k --verbose_failures \u002F\u002Ftensorflow\u002Ftools\u002Fpip_package:build_pip_package\n",[349,554,552],{"__ignoreMap":351},[11,556,557],{},"Пару часов\u002Fсуток и сборка завершится.\nОстанется только установить все это дело в Python\nДля этого выполни:",[342,559,562],{"className":560,"code":561,"language":347},[345],"bazel-bin\u002Ftensorflow\u002Ftools\u002Fpip_package\u002Fbuild_pip_package \u002Ftmp\u002Ftensorflow_pkg\n",[349,563,561],{"__ignoreMap":351},[11,565,566],{},"И установи получившийся PIP пакет:",[342,568,571],{"className":569,"code":570,"language":347},[345],"pip install \u002Ftmp\u002Ftensorflow_pkg\u002Ftensorflow-version-tags.whl\n",[349,572,570],{"__ignoreMap":351},[11,574,575],{},"Готово.",[18,577,579],{"id":578},"важное-замечание","Важное замечание",[11,581,582,583,586],{},"Bazel помимо остальных жирных минусов имеет еще один жирнющий:\nОн жрет памяти больше чем 200 хромов. Так один раз он сожрал все данные ему 16Гб оперативной памяти и благополучно повесил сервер в OOM. Так что оперативку брать надо с запасом(по совету проверенных комрадов из Google минимум 16), и если версия bazel достаточно свежая, то использовать ключ ",[349,584,585],{},"--local_ram_resources=4096"," подставьте свое доступное количество памяти, тогда bazel будет пытаться себя ограничивать в данных рамках. Однако выходит у него не всегда ._.",[18,588,590],{"id":589},"небольшое-пояснение","Небольшое пояснение",[11,592,593],{},"Очевидно, что в моем случае, это все еще медленно, однако у меня есть ощущение, что еще быстрее не прибегая к использованию GPU уже не получится. Однако даже на этих ресурсах хорошо видно, насколько более детальный подбор инструкций и библиотек для конкретного железа ускоряет процесс.",[595,596],"hr",{},[11,598,599],{},"Спасибо за внимание!",{"title":351,"searchDepth":601,"depth":601,"links":602},2,[603,604,605,611,616,617],{"id":20,"depth":601,"text":21},{"id":36,"depth":601,"text":37},{"id":336,"depth":601,"text":337,"children":606},[607,609,610],{"id":358,"depth":608,"text":359},3,{"id":365,"depth":608,"text":366},{"id":372,"depth":608,"text":373},{"id":399,"depth":601,"text":400,"children":612},[613,614,615],{"id":406,"depth":608,"text":407},{"id":524,"depth":608,"text":525},{"id":544,"depth":608,"text":545},{"id":578,"depth":601,"text":579},{"id":589,"depth":601,"text":590},"2020-02-26",false,"md","\u002Fimages\u002Ftf_logo_social.png",true,{},"\u002Fru\u002Fposts\u002Fcode_n_shit\u002Ftensorflow_from_source",{"title":5,"description":13},"ru\u002Fposts\u002Fcode_n_shit\u002Ftensorflow_from_source",[628,629,349],"ml","machine learing","zaMmO2DZJ_ZKX5WCfZZSk7PaGBISBQWZDcsJmuEfNvI",[],1790369235096]