راه اندازی کودا (CUDA) در داکر (DOCKER)

در این مقاله قصد داریم توضیح بدیم که CUDA چیه و چه قابلیتی رو برای ما فراهم کرده که در ابتدا توضیحات مختصری در مورد CPU , GPU و تفاوت اونا میگیم در ادامه کودا رو مورد برررسی قرار میدیم تعریفش میکنیم در مورد مباحثی که برای خیلی ها اشتباه ایجاد میکنه پیرامون کودا و در نهایت هم که بخش عملی این پست هستش کانفیگ یک سرور لینوکسی برای استفاده از GPU تحت داکر رو انجام میدیم که با نصب درایور انویدیا و توضیحات شروع میشه و در نهایت کانتینر تنسرفلو رو ران میکنیم و تستش میکنیم که ایا از GPU استفاده میکنه یا نه.سی پی یو CPUپردازنده، واحد پردازش مرکزی کامپیوتر است که اجرای تمام دستورالعمل‌ها رو مدیریت می‌کنه و اغلب به اون مغز کامپیوتر میگن.جی پی یو GPUپردازنده گرافیکی یا Graphic Processor Unit که به اختصار GPU گفته می شه، قطعه ای است که روی کارت های گرافیک و همچنین گرافیک های آنبورد قرار داده می شه. این قطعه به صورت مجزا از CPU کار پردازش و رندرینگ تصاویر رو انجام می ده. کارت گرافیک اطلاعات رو برای پردازش تصویر ترجمه می‌کنه و خروجی رو روی صفحه نمایش نمایش میده. هر چی کارت گرافیک در نمایش تصویر سریعتر باشد، خروجی بصری بهتری داریم.تفاوت اصلی CPU و GPUنکته ای که در مورد این تفاوت باید در نظر داشته باشیم و خیلی ها درباره اون اشتباه میکنن، نحوه کار و دستوراتی هست که اجرا می‌شه. در واقع CPU به ازای هر هسته تو هر کلاک می‌تونه یک دستور متفاوت انجام بده در نتیجه یک CPU با ۴ هسته در هر کلاک ۴ تا دستور که می‌تونن کاملا بی‌ربط به هم باشن رو انجام می‌ده. اما در GPU تو هر کلاک تعداد محدودی دستور روی حجم بزرگی از داده بخش بندی شده اجرا می‌شه. به طور مثال همه ۲۵۶۰ هسته یک GTX1080 در هر کلاک فقط یک یا چند دستور محدود رو می‌تونن اجرا کنن اما هر کدوم دارن اون دستور رو روی بخشی از داده‌ها اجرا می‌کنن. یک تفاوت مهم دیگه اینکه تعداد دستورات در GPU نسبت به CPU خیلی کمتره و فقط برای محاسبات ریاضی مناسبه اما CPU توانایی انجام عملیات خیلی گسترده‌تری داره.کودا CUDAطبق توضیحات انویدیا CUDA در واقع یک پلتفرم پردازش موازی و مدل برنامه نویسی هستش که توسط انویدیا ساخته شده .تعریف CUDA رو میشه به دو قسمت تقسیم کرد که قسمت اول میشه Parallel Computing Platform و قسمت دوم Programming Model.کودا در واقع سرواژه Compute Unified Device Architecture هستش که همونطور که از تعریفش مشخصه یک معماری ای هستش که این قابلیت رو به GPU میده که پردازش های سنگین رو خیلی سریع و همزمان اجرا کند.توضیحات بیشتر در مورد قسمت دوم تعریف در ادامه میشه.کانفیگ سرور لینوکسی از صفر برای استفاده از GPUنصب NVIDIA-Driverبرای استفاده از جی پی یو در هر سیستم عامل و به هر شکلی قطعا نیاز به نصب بودن درایور انویدیا متناسب با سیستم عامل میزبان هستش.نصب انویدیا درایور ۶ مرحله داره که در زیر هر مرحله رو جداگونه بررسی میکنیم.1- بررسی اینکه GPU کودا (CUDA) رو ساپورت میکنه یا نهlspci | grep -i nvidiaدستور lspci یک ابزار کاربردی در سیستم‌های لینوکس است که برای یافتن اطلاعات مربوط به گذرگاه‌های PCI و دستگاه‌های متصل به زیرسیستم PCI استفاده میشه.در ادامه باید مدل GPU رو داخل سایت زیر بررسی کرد برای پشتیبانی CUDA https://developer.nvidia.com/cuda-gpus 2-بررسی اینکه ورژن استانداردی از لینوکس نصب هست یا نهuname -m && cat /etc/&release3-بررسی اینکه system build tools هایی مانند GCC نصب هست یا نهgcc --version4-بررسی اینکه سیستم linux header مناسبی داره یا نه و نصب آن هاuname -r #Install linux headers sudo apt-get install linux-headers-$(uname -r)5-انتخاب NVIDIA-DRIVER مناسب برای سیستم عامل#first way ubuntu-drivers devices #second way apt search nvidia-driver6-نصب درایور#install driver sudo apt install nvidia-drver-515-server #reboot system sudo rebootبعد از نصب درایور متناسب با سیستم عامل اگر نصب با موفقیت انجام شده باشه با استفاده از دستور nvidia-smi که همراه درایور نصب میشه روی سیستم میتونیم چک کنیم.کاربرد NVIDIA-SMIاینترفیس مدیریت سیستم های انویدیا NVIDIA (NVIDIA-SMI) یک ابزار خط فرمانه که بر پایه کتابخانه مدیریت NVIDIA (NVML) ساخته شده که برای کمک به مدیریت و نظارت به دستگاه های گرافیکی NVIDIA طراحی شده .کاربرد NVMLیک API نوشته شده با زبان C هستش که برای نظارت و مدیریت وضعیت‌های مختلف دستگاه‌های GPU NVIDIA نوشته شده که امکان دسترسی مستقیم به پرس و جوها و دستورات خروجی از طریق NVIDIA-SMI رو فراهم می کنه.کودا تولکیت(CUDA TOOLKIT)کودا تولکیت (CUDA TOOLKIT)توسط انویدیا معرفی شد و هر چیزی که برای توسعه برنامه های GPU مورد نیاز هست رو داخل خودش داره مثل کامپایلرهای مناسب برای برنامه های CUDA ,کتابخونه های مختلف مناسب برای برنامه های جی پی یو , IDES , دیباگر و CUDA RUNTIME .با نصب nvidia-driver دیگه نیازی به نصب درایور cuda روی سرور نیست بخاطر اینکه cuda driver همراه درایور انویدیا نصب میشوه و ورژن آن هم بعد از چک کردن دستور nvidia-smi مشخص هستش.دقت کنید که تا به اینجا ما یک سرور لینوکسی ابونتو داریم که فقط انویدیا درایور رو روی اون نصب کردیم که همراه اون درایور کودا هم نصب شده اما هنوز کودا تولکیت که بالاتر توضیح دادیم رو نصب نکردیم.کاربرد NVCCدر واقع nvcc کامپایلر انویدیا کودا هستش و اگر کودا تولکیت روی سیستم ما نصب باشه میتونیم با استفاده از دستور nvcc –version چک کنیم.تعریف CUDNNاین کتابخونه برای کار های شبکه های عصبی عمیق با استفاده از GPU استفاده میشه و میشه ازش در چارچوب‌های یادگیری ماشینی پیشرفته، مانند TensorFlow Google، PyTorch و غیره استفاده کرد.تفاوت CUDA DRIVER LIBRARY و CUDA RUNTIME LIBRARYکتابخانه CUDA (درایور): با درایور NVIDIA نصب شده و برای برنامه نویسی سطح پایین CUDA در نظر گرفته شده.shared library name : libcuda.soheader file : cuda.hکتابخانه CUDA (Runtime): کتابخانه CUDA Runtime با NVIDIA CUDA Toolkit نصب شده است و برای برنامه نویسی CUDA سطح بالا در نظر گرفته شده.shared library name : libcudart.soheader file : cuda_runtime.hدر حالی که CUDA Driver API و Runtime API عملکردهای مشترکی دارند، در بیشتر سناریوها، استفاده از CUDA Runtime API برای حل مشکل کافیه و کد بسیار ساده‌تر هستش.استفاده از GPU تحت داکر(DOCKER)برای استفاده از GPU تحت داکر فقط نیاز به نصب NVIDIA-DRIVER و NVIDIA CONTAINER RUNTIME هست, هیچ نیازی به نصب CUDA TOOLKIT نیستش.برای اجرای کانتینر های داکری طوری که بتونن از GPU استفاده کننن از فلگ GPUS --ALL استفاده میکنیم و برای اینکار حتما باید NVIDIA CONTAINER RUNTIME نصب باشه.به نسخه Docker خود با docker -v توجه کنید. نسخه های قبل از 19.03 به nvidia-docker2 و فلگ runtime=nvidia نیاز دارن. در نسخه های بعد از 19.03، از بسته nvidia-container-toolkit و فلگ GPUS --ALL. کاربرد NVIDIA-CONTAINER-RUNTIMEیک کانتینر رانتایم اگاه از وجود GPU هستش که کاملا با OCI های مورد استفاده از در داکر و بقیه کانتینر انجین ها سازگار هستش که کار ساختن برنامه های GPU با استفاده از داکر رو راحت تر میکنهاجرا و تست کانتینر هابرای استفاده از داکر ایمیج تنسرفلو به شکلی که از GPU بتونه استفاده کنه باید ۳ تا مورد روی سیستم هاست نصب باشهانویدیا درایورداکرانویدیا داکر ساپورتنصب انویدیا ساپورت برای داکر (nvidia-docker2/nvidia-container-runtime)distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \ && curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg \ && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get update sudo apt-get install -y nvidia-docker2 sudo systemctl restart dockerتست دسترسی به GPU با استفاده از دستور NVIDIA-SMI از داخل کانتینر انویدیا کوداsudo docker run --rm --gpus all nvidia/cuda:11.7.0-base-ubuntu22.04 nvidia-smiدقت کنید که فلگ GPUS --ALL اگر انویدیا داکر ساپورت روی سیستم هاست نصب نباشه ارور میدهه و کانتینر اصلا اجرا نمیشود.نصب و کانفیگ تنسرفلو به کمک داکر و استفاده از GPU:docker pull tensorflow/tensorflow:latest-gpu-jupyter docker run --gpus all -it --rm tensorflow/tensorflow:latest-gpu \ python -c &quotimport tensorflow as tf; print(tf.reduce_sum(tf.random.normal([1000, 1000])))&quotبررسی اینکه آیا کانتینر تنسرفلو به GPU دسترسی داره یا نه:tf.config.list_physical_devices('GPU') gpu_available = tf.test.is_gpu_available()is_cuda_gpu_available = tf.test.is_gpu_available(cuda_only=True) is_cuda_gpu_min = tf.test.is_gpu_available(True, (3,0))