Leifeng.com'un notu: Bu makalenin yazarı Tianqing'dir. Orijinal metin sütunda yer almaktadır.Dünya o kadar büyük ki kod yazmak istiyorum Leifeng.com bunu yayınlamaya yetkilidir.
Proje adresi: QuantumLiu / tf_gpu_manager
***
Güncelleme: Pytorch'u destekleyin
***
git klon https://github.com/QuantumLiu/tf_gpu_manager
Manager.py'yi eğitim dizininize koyun.
Bir sonraki kod bloğu işlemi için cihazı otomatik olarak seçmek üzere gm.auto_choice ile doğrudan kullanın.
tensorflow'u tf olarak içe aktar
yöneticiden GPUManager içe aktar
keras.layers LSTM'den
gm = GPUManager
gm.auto_choice ile:
x = tf.placeholder (tf.float32, şekil = (Yok, 20,64))
y = LSTM (32) (x)
Derin öğrenme teknolojisinin hızla gelişmesiyle birlikte, derin öğrenme görevleri için veri ölçeği ve hesaplamalar da gittikçe büyüyor.İyi bir iş yapmak istiyorsanız, güçlü bir GPU iş istasyonu olmadan yapamazsınız.
Güçlü tek kart performansı gerektirmesinin yanı sıra, GPU sayısı da oldukça önemlidir.
Aşağıdaki nedenlerden dolayı, çoklu GPU iş istasyonları büyük laboratuvarlarda standart ekipman haline gelmiştir:
Genel olarak konuşursak, bir derin öğrenme projesinin, bir veya birkaç iş istasyonunu paylaşan bir laboratuvarda veya grupta birden çok kişi tarafından tamamlanması gerekir. Bir ana bilgisayarda birden fazla GPU daha kullanışlıdır.
Deneyler, birden çok parametre seti veya karşılaştırmalı deneyler gerektirir. Birden çok GPU'yu paralel olarak çalıştırarak zamandan tasarruf edin.
Modelin büyük miktarda hesaplaması vardır ve hesaplama için modeli birden fazla GPU'ya tahsis etmek gerekir.
Artık Tensorflow ve pytorch gibi genel derin öğrenme çerçevelerinin tümü çoklu GPU eğitimini destekliyor.
Örneğin, Tensorflow'da aygıt işlevi, işlemi gerçekleştirmek için kullanılan GPU aygıtının bir bağlam yöneticisi nesnesini döndüren tensorflow \ python \ framework'te tanımlanır.
def aygıt (aygıt_adı_veya_işlevi):
Varsayılan grafiği kullanarak "Graph.device" için "" "Sarmalayıcı.
Görmek
@ {tf.Graph.device}
daha fazla ayrıntı için.
Args:
device_name_or_function: Bağlamda kullanılacak aygıt adı veya işlevi.
İadeler:
Yeni oluşturulan operasyonlar için kullanılacak varsayılan cihazı belirten bir bağlam yöneticisi.
"" "
get_default_graph.device (aygıt_adı_veya_işlevi) döndür
Eğitim komut dosyamızdaki with ifadesini kullanmak, bir sonraki işlemin belirli bir GPU üzerinde gerçekleştirilmesini belirtebilir.
tf.device ('/ gpu: 2') ile:
a = tf.constant (, şekil =, ad = 'a')
b = tf.constant (, şekil =, ad = 'b')
c = tf.matmul (a, b)
İşte soru geliyor:
Eğitim komut dosyaları yazarken hangi GPU'nun kullanılabilir olduğunu nasıl anlarsınız?
Ya aynı gruptan biri bir deney yaparsa ve benimle çatışırsa?
Bu komut dosyası gelecekte bir noktada çalıştırıldığında duruma göre değiştirilecek mi?
İş arkadaşları deneyi yeniden oluşturmak için kodumu kullandılar. GPU yapılandırma ortamı farklı. GPU'ları bile olmayabilir, bu yüzden kodu değiştirmek istiyorlar mı?
Tabii ki, yoldaki tüm geliştiriciler, nvidia-smi'nin grafik kartı bilgilerini sorgulayabileceğini, GPU belleğini, sıcaklığı ve güç kullanımını kontrol edebileceğini ve ardından uygun GPU'yu seçebileceğini bilir.
Bu komutu her eğitimden önce uygulamak ve iyi bir ekiple iyi bir iletişim sürdürmek, yukarıdaki iki sorunu 1, 2 çözebilir, ancak problem 3 ve 4'ün çözülmesi hala zordur.
Ve sık sık kardeşler ve meslektaşlarla kart almak verimliliği etkilemez mi?
Komut dosyalarını değiştirmeden ve ekip üyeleriyle iletişim kurmadan boşta olan GPU cihazlarını otomatik olarak seçebilen bir çözüme ihtiyacımız var.
nvidia-smi, NVIDIA tarafından sağlanan GPU durum yönetimi ve izleme için resmi bir komut satırı yazılımıdır. Diğer komut satırı yazılımları gibi, nvidia-smi'nin de birçok argümanı vardır.
Belgeleri okuyarak ve eski sürücünün deneyimini öğrenerek, --query-gpu seçeneğinin GPU durum bilgilerini sorgulamayı ve biçimlendirilmiş bilgileri döndürmeyi belirtebileceğini biliyoruz.
Komutu çalıştırarak:
nvidia-smi - yardım-sorgu-gpu
Desteklenen tüm sorgu parametrelerini aldık (tek tek numaralandırılamayacak kadar çok)
En kullanışlı parametreler eski sürücü tarafından özetlenmiştir:
Ve index, name, power.draw, power.limit buldum
Yani temel bir fikrimiz var, Os.popen ile ilgili komutları yürütün, metin bilgilerini ayrıştırın ve döndürün .
def ayrıştırma (satır, qargs):
'' '
hat:
bir metin satırı
qargs:
sorgu bağımsız değişkenleri
dönüş:
bir gpu bilgi emri
Nvidia-smi tarafından döndürülen csv formatındaki bir metin satırını geçme
Nvidia-smi tarafından döndürülen csv formatındaki bir metin satırını ayrıştırın
'' '
numberic_args = # Sayılabilir parametreler
power_manage_enable = lambdav: (Not'Not Support'inv) #lambda ifadesi, grafik kartının güç yönetimi için iyi olup olmadığı (dizüstü bilgisayar için uygun olmayabilir)
to_numberic = lambdav: float (v.upper.strip.replace ('MIB', ''). replace ('W', '')) # Birim dizesi ile birimi kaldır
process = lambdak, v: ((int (to_numberic (v)) ifpower_manage_enable (v) else1) ifkinnumberic_argselsev.strip)
return {k: süreç (k, v) çatal, vinzip (qargs, line.strip.split (','))}
def query_gpu (qargs =):
'' '
qargs:
sorgu bağımsız değişkenleri
dönüş:
bir dikt listesi
GPU bilgilerini sorgulama
GPU bilgilerini sorgulama
'' '
qargs = + qargs
cmd = 'nvidia-smi --query-gpu = {} --format = csv, noheader'.format (', '. join (qargs))
sonuçlar = os.popen (cmd) .readlines
dönüş
Artık GPU durumunu öğrenebilirsiniz, ancak GPU boşluğunu nasıl ölçebilir ve sıralayabilirsiniz?
Derin öğrenme alanında, GPU boşluğu iki ana gösterge ile ölçülebilir: video belleği boşta ve güç boşta.
Video belleği işgal, mutlak alan işgal ve işgal oranına bölünmüştür.
Son olarak, ölçmek için üç gösterge kullanıyoruz:
Boş video bellek alanı
Kalan video bellek oranı
Mevcut güç / nominal güç
Daha önce, tüm GPU bilgilerini bir liste olarak saklamıştık ve her liste bir gpu bilgileri sözlüğüdür.
Mevcut GPU'ları sıralamak için yerleşik işlevi kullanırız.
Örneğin, video belleğine göre kullanın:
def_sort_by_memory (self, gpus, by_size = False):
by_size ise:
print ('Boş hafıza boyutuna göre sıralandı')
sıralı dönüş (gpus, anahtar = lambda d: d, ters = Doğru)
Başka:
print ('Boş hafıza oranına göre sıralı')
sıralı dönüş (gpus, anahtar = lambda d: float (d) / d, ters = Doğru)
Örnek nesnesinin ömrü boyunca GPU durumunu güncelleyecek ve ayrılmış GPU'yu kaydedecek bir GPUManager sınıfı tanımlıyoruz.
Örneklemeden sonra, auto_choice yöntemi çağrılarak bir tf.device nesnesi doğrudan döndürülür.
Aynı zamanda kullanıcının bilgisayarında GPU bulunmayabileceği de göz önünde bulundurularak bir istisna işleme mekanizması eklenmiştir.
def check_gpus: '' '
GPU kullanılabilir kontrolü
referans:
'' '
all_gpus =
all_gpus değilse:
print ('Bu komut dosyası yalnızca NVIDIA GPU'ları yönetmek için kullanılabilir, ancak cihazınızda GPU bulunamadı')
Yanlış dönüş
elif, os.popen'de 'NVIDIA Sistem Yönetimi' değildir ('nvidia-smi -h'). okuyun:
print ("'nvidia-smi' aracı bulunamadı.")
Yanlış dönüş
True döndür
check_gpus: def ayrıştırma (satır, qargs) ise:
'' '
hat:
bir metin satırı
qargs:
sorgu bağımsız değişkenleri
dönüş:
bir gpu bilgi emri
Nvidia-smi tarafından döndürülen csv formatındaki bir metin satırını geçme
Nvidia-smi tarafından döndürülen csv formatındaki bir metin satırını ayrıştırın
'' '
numberic_args = #countable parametreler
power_manage_enable = lambda v: (v'de 'Desteklenmiyor' değil) #lambda ifadesi, grafik kartının güç yönetimi için iyi olup olmadığı (dizüstü bilgisayar güç yönetimi için iyi olmayabilir)
to_numberic = lambda v: float (v.upper.strip.replace ('MIB', ''). replace ('W', '')) # Birim dizesi ile birimi kaldır
process = lambda k, v: ((int (to_numberic (v)) if power_manage_enable (v) else 1) eğer numberic_args else v.strip içinde k ise)
{k: process (k, v) for k, v in zip (qargs, line.strip.split (','))}
def query_gpu (qargs =):
'' '
qargs:
sorgu bağımsız değişkenleri
dönüş:
bir dikt listesi
GPU bilgilerini sorgulama
GPU bilgilerini sorgulama
'' '
qargs = + qargs
cmd = 'nvidia-smi --query-gpu = {} --format = csv, noheader'.format (', '. join (qargs))
sonuçlar = os.popen (cmd) .readlines
dönüş
def by_power (d): '' '
gpus'u güce göre sıralamak için yardımcı işlev
'' '
power_infos = (d, d)
varsa (v == 1, power_infos'ta v için):
print ('GPU {} için güç yönetimi yapamaz'. format (d))
dönüş 1
dönüş şamandırası (d) / d
sınıf GPUManager: '' '
qargs:
sorgu bağımsız değişkenleri
Mevcut tüm GPU cihazlarını listeleyebilen ve bunları sıralayabilen ve en özgür olanı seçebilen bir yönetici.
GPU cihaz yöneticisi, mevcut tüm GPU cihazlarını sıralamayı, sıralamayı ve otomatik olarak en çok boşta olan cihazı seçmeyi düşünün. Bir GPUManager nesnesinde, her bir GPU'nun belirlenmiş olup olmadığını kaydeder ve belirtilmemiş GPU tercih edilir.
'' '
def __init __ (self, qargs =):
'' '
'' '
self.qargs = qargs
self.gpus = sorgu_gpu (qargs)
self.gpus'daki gpu için:
gpu = Yanlış
self.gpu_num = len (self.gpus)
def _sort_by_memory (self, gpus, by_size = False):
by_size ise:
print ('Boş hafıza boyutuna göre sıralandı')
sıralı dönüş (gpus, anahtar = lambda d: d, ters = Doğru)
Başka:
print ('Boş hafıza oranına göre sıralı')
sıralı dönüş (gpus, anahtar = lambda d: float (d) / d, ters = Doğru)
def _sort_by_power (self, gpus): sıralı döndür (gpus, key = by_power)
def _sort_by_custom (self, gpus, key, reverse = False, qargs =):
isinstance (key, str) ve (key in qargs):
sıralı dönüş (gpus, anahtar = lambda d: d, ters = ters)
eğer örnek (anahtar, tür (lambda a: a)):
sıralı dönüş (gpus, anahtar = anahtar, ters = ters)
ValueError değerini yükselt ("'anahtar' argümanı sorgu argümanlarında bir işlev veya anahtar olmalıdır, lütfen nvidia-smi belgesini okuyun")
def auto_choice (öz, mod = 0): '' '
mod:
0: (varsayılan) boş hafıza boyutuna göre sıralı
dönüş:
bir TF cihaz nesnesi
Belirtilmemiş olan en serbest GPU cihazını otomatik seçme
olanlar
En boşta olan GPU'yu otomatik olarak seçin
'' '
old_infos için, zip içinde new_infos (self.gpus, query_gpu (self.qargs)):
old_infos.update (new_infos)
unspecified_gpus = veya self.gpus
eğer mod == 0:
print ('GPU cihazının seçilmesi en büyük boş belleğe sahiptir ...')
selected_gpu = self._sort_by_memory (unspecified_gpus, True)
elif modu == 1:
print ('GPU cihazını seçmek en yüksek boş hafıza oranına sahiptir ...')
selected_gpu = self._sort_by_power (unspecified_gpus)
elif modu == 2:
print ('GPU aygıtını güce göre seçme ...')
selected_gpu = self._sort_by_power (unspecified_gpus)
Başka:
print ('Uygun olmayan bir mod verildiğinde, hafıza tarafından seçilecek')
selected_gpu = self._sort_by_memory (unspecified_gpus)
selected_gpu = Doğru
index = selected_gpu
print ('GPU {i} kullanarak: \ n {bilgi}'. format (i = dizin, bilgi = '\ n'.join ()))
dönüş tf.device ('/ gpu: {}'. format (dizin))
Başka:
ImportError'ı artırın ('GPU kullanılabilir kontrolü başarısız oldu'