CPU TENSOR ที่ตรึงเร็วกว่า <-> GPU Pytorch Variabe Transfer และ GPU Tensor <-> การถ่ายโอนตัวแปร GPU Pytorch ในบางกรณี
เนื่องจากสำหรับบาง cpu การใช้เทนเซอร์ Pytorch CPU ที่ถูกตรึงนั้นเร็วกว่าการใช้ Tensors cuda (ดูว่า 'มันทำงานได้อย่างไร' สำหรับรายละเอียดเพิ่มเติม) ฉันจึงสร้างชั้นเรียน cpu Tensor ทั่วไป PytorchModelFactory และ PytorchOptimizerFactory GPUPytorchModelFactory และ GPUPytorchOptimizerFactory คลาสดั้งเดิมยังคงอยู่ในห้องสมุดดังนั้นจึงไม่มีรหัสที่มีอยู่โดยใช้ SpeedTorch เอกสารได้รับการอัปเดตเพื่อรวมคลาสใหม่เหล่านี้
ห้องสมุดนี้จะหมุนรอบเทนเซอร์ cupy ที่ตรึงไว้ที่ CPU ซึ่งสามารถทำได้ 3.1x CPU ที่เร็วขึ้น 3.1x -> การถ่ายโอน GPU มากกว่า Pytorch ปกติที่ตรึง CPU Tensors สามารถและ GPU ที่เร็วขึ้น 410x -> การถ่ายโอน CPU ความเร็วขึ้นอยู่กับปริมาณข้อมูลและจำนวนคอร์ CPU ในระบบของคุณ (ดูส่วนที่ทำงานสำหรับรายละเอียดเพิ่มเติม)
ห้องสมุดมีฟังก์ชั่นสำหรับการฝึกอบรม Embeddings; มันสามารถโฮสต์การฝังตัวใน CPU RAM ในขณะที่ไม่ได้ใช้งาน, ประหยัด GPU RAM
ตอนแรกฉันสร้างห้องสมุดนี้เพื่อช่วยฝึกอบรมการฝังตัวจำนวนมากซึ่ง GPU อาจมีปัญหาในการถือครองใน RAM ในการทำเช่นนี้ฉันพบว่าการโฮสต์การฝังตัวใน CPU สามารถช่วยให้บรรลุเป้าหมายนี้ได้ ระบบฝังตัวใช้การฝึกอบรม Sprase; เพียงเศษเสี้ยวของพ่ายแพ้ทั้งหมดเท่านั้นที่เข้าร่วมในขั้นตอนการส่งต่อ/อัปเดตส่วนที่เหลืออยู่ไม่ได้ใช้งาน ดังนั้นฉันจึงคิดว่าทำไมไม่เก็บพารามิเตอร์ที่ไม่ได้ใช้งานออกจาก GPU ในระหว่างขั้นตอนการฝึกอบรม? สำหรับสิ่งนี้ฉันต้องการ CPU ที่รวดเร็ว -> การถ่ายโอน GPU
สำหรับ backstory เต็มรูปแบบโปรดดูหน้า devpost
https://devpost.com/software/speedtorch-6w5unb
ด้วย CPU-> GPU ที่รวดเร็ววิธีการสนุก ๆ มากมายสามารถพัฒนาได้สำหรับฟังก์ชันการทำงานซึ่งก่อนหน้านี้คนคิดว่าอาจเป็นไปไม่ได้
️รวม Speedtorch ลงในท่อข้อมูลของคุณสำหรับการถ่ายโอนข้อมูลที่รวดเร็วไปยัง/จาก CPU <-> GPU
️เพิ่มพารามิเตอร์การฝึกอบรมผ่านที่เก็บ CPU ตราบใดที่คุณมี CPU RAM เพียงพอคุณสามารถโฮสต์การฝังตัวจำนวนใดก็ได้โดยไม่ต้องกังวลเกี่ยวกับ GPU RAM
️ใช้ Adadelta, Adamax, RMSPROP, RPROP, ASGD, ADAMW และ ADAM Optimizers สำหรับการฝึกอบรมการฝังตัวแบบเบาบาง ก่อนหน้านี้มีเพียง Spraseadam, Adagrad และ SGD ที่เหมาะสมเนื่องจากมีเพียงสิ่งเหล่านี้เท่านั้นที่รองรับการไล่ระดับสีกระจัดกระจายโดยตรง
(แก้ไข 9-20-19 หนึ่งในนักพัฒนา Pytorch ชี้ให้เห็นข้อบกพร่องเล็ก ๆ น้อย ๆ ในรหัสการทำเครื่องหมายของม้านั่งต้นฉบับค่าและรหัสได้รับการอัปเดตแล้ว)
นี่คือโน้ตบุ๊กเปรียบเทียบการถ่ายโอนผ่าน Speedtorch vs Pytorch Tensors โดยมีทั้ง CPU และ CUDA Tensors การทดสอบทั้งหมดทำด้วยอินสแตนซ์ colab กับ Tesla K80 GPU และซีพียูหลัก 2 ตัว
อัปเดต 10-17-19: Google Colab เป็นมาตรฐานด้วย 4 CPUs CORE ดังนั้นสมุดบันทึกนี้จะให้ผลลัพธ์ที่แตกต่างจากที่รายงานไว้ด้านล่างเนื่องจาก Kernals การจัดทำดัชนีของ Pytorch มีประสิทธิภาพมากขึ้นเมื่อจำนวนคอร์ CPU เพิ่มขึ้น
https://colab.research.google.com/drive/1pxhbmbzqtiq_nlfguianpf_mfpiqskks
สมุดบันทึกนี้เพิ่มการถ่ายโอนข้อมูลของ 131,072 float32 embeddings ของมิติ 128, ไปและกลับจากตัวแปร cupy/pytorch และตัวแปร pytorch โดยมี n = 100 CPU ของ Google Colab มี 4 คอร์ซึ่งมีผลกระทบต่อความเร็วในการถ่ายโอน ซีพียูที่มีจำนวนแกนจำนวนมากขึ้นจะเห็นคำแนะนำน้อยลงในการใช้ speedtorch
ตารางด้านล่างเป็นบทสรุปของผลลัพธ์ การถ่ายโอนข้อมูลจาก Pytorch Cuda Tensors ไปยังตัวแปรการฝัง Cuda Pytorch นั้นเร็วกว่า Speedtorch เทียบเท่า แต่สำหรับการถ่ายโอนประเภทอื่น ๆ ทั้งหมด Speedtorch เร็วกว่า และสำหรับผลรวมของทั้งสองขั้นตอนการถ่ายโอนไปยัง/จากการฝัง CUDA pytorch, Speedtorch เร็วกว่า pytorch เทียบเท่าสำหรับทั้ง GPU ปกติและ CPU ตรึงเทนเซอร์
ฉันสังเกตเห็นว่าอินสแตนซ์ที่แตกต่างกันของผลลัพธ์ในผลลัพธ์ความเร็วที่แตกต่างกันดังนั้นโปรดจำไว้ว่าในขณะที่ตรวจสอบผลลัพธ์เหล่านี้ การทำงานส่วนตัวของสมุดบันทึก colab อาจส่งผลให้ค่าต่างกันแม้ว่าลำดับของแมกเน็ตของผลลัพธ์จะเหมือนกัน
เวลาถ่ายโอนในตารางต่อไปนี้จะได้รับในไม่กี่วินาที การเปรียบเทียบนี้ถูก preformed ด้วยอินสแตนซ์ colab ที่ CPU มี 2 คอร์ Colab มีอินสแตนซ์ที่ชำระเงินรุ่น Pro ซึ่งเป็น 4 ซีพียูหลักดังนั้นการเปรียบเทียบต่อไปนี้จะไม่สะท้อนให้เห็นถึงอินสแตนซ์เหล่านั้น
| ประเภทเทนเซอร์ | ถึงตัวแปร Cuda Pytorch | การเปรียบเทียบ |
|---|---|---|
| Speedtorch (cuda) | 0.0087 | 6.2x ช้ากว่า pytorch เทียบเท่า |
| Speedtorch (Pinnedcpu) | 0.0154 | 3.1x เร็วกว่า pytorch เทียบเท่า |
| Pytorch (Cuda) | 0.0014 | 6.2x เร็วกว่า speedtorch เทียบเท่า |
| Pytorch (Pinnedcpu) | 0.0478 | 3.1x ช้ากว่า speedtorch เทียบเท่า |
| ประเภทเทนเซอร์ | จากตัวแปร Cuda Pytorch | การเปรียบเทียบ |
|---|---|---|
| Speedtorch (cuda) | 0.0035 | 9.7x เร็วกว่า pytorch เทียบเท่า |
| Speedtorch (Pinnedcpu) | 0.0065 | 410x เร็วกว่า pytorch เทียบเท่า |
| Pytorch (Cuda) | 0.0341 | 9.7x ช้ากว่า speedtorch เทียบเท่า |
| Pytorch (Pinnedcpu) | 2.6641 | ช้ากว่า 410X เทียบเท่ากับ speedtorch |
| ประเภทเทนเซอร์ | ผลรวมของตัวแปร to/จาก cuda pytorch | การเปรียบเทียบ |
|---|---|---|
| Speedtorch (cuda) | 0.0122 | 2.9x เร็วกว่า pytorch เทียบเท่า |
| Speedtorch (Pinnedcpu) | 0.0219 | เร็วกว่า pytorch 124x เทียบเท่า |
| Pytorch (Cuda) | 0.0355 | 2.9x ช้ากว่า speedtorch เทียบเท่า |
| Pytorch (Pinnedcpu) | 2.7119 | ช้ากว่า speedtorch 124x เทียบเท่า |
เกณฑ์มาตรฐานที่คล้ายกันถูกคำนวณสำหรับการถ่ายโอนไปยัง/จาก Pytorch CUDA Optimizers ผลลัพธ์นั้นเหมือนกันนี่คือสมุดบันทึกที่ใช้สำหรับการเปรียบเทียบการเพิ่มประสิทธิภาพ
https://colab.research.google.com/drive/1y2nehd8xj-ixfjkj2qwua_ujqjbbhhhj5
แม้ว่าเทนเซอร์ของ Speedtorch จะเร็วกว่าของ Pytorch แต่ข้อเสียเปรียบคือ Tensors ของ Speedtorch ใช้หน่วยความจำมากขึ้น อย่างไรก็ตามเนื่องจากการถ่ายโอนข้อมูลสามารถเกิดขึ้นได้เร็วขึ้นคุณสามารถใช้ Speedtorch เพื่อเพิ่มจำนวนการฝังตัวที่ผ่านการฝึกอบรมในสถาปัตยกรรมของคุณโดยถือพารามิเตอร์ทั้งใน GPU และ CPU
ตารางนี้เป็นบทสรุปของการเปรียบเทียบที่ทำใน Google Colab จากประสบการณ์ของฉันดูเหมือนว่าจะมีการเปลี่ยนแปลงบางอย่างในค่าหน่วยความจำที่รายงานใน colab, +-0.30 GB ดังนั้นโปรดจำไว้ว่าในขณะที่ตรวจสอบตัวเลขเหล่านี้ ค่าใช้จ่ายสำหรับการถือ 10,000x128 float32 เทนเซอร์
| ประเภทเทนเซอร์ | CPU (GB) | GPU (GB) |
|---|---|---|
| cupy pinnedcpu | 9.93 | 0.06 |
| pytorch pinnedcpu | 6.59 | 0.32 |
| CUDA | 0.39 | 9.61 |
| Pytorch Cuda | 1.82 | 5.09 |
แม้ว่าเวลาของ Pytorch ถึง/จากสำหรับ Pytorch GPU Tensor <-> ตัวแปร Pytorch Cuda นั้นไม่เร็วเท่ากับ Cupy เทียบเท่ากันความเร็วยังคงใช้งานได้ ดังนั้นหากหน่วยความจำยังคงเป็นข้อกังวลวิธีที่ดีที่สุดของทั้งสองโลกคือ CPU CPU ของ Speedtorch ตรึงเทนเซอร์เพื่อเก็บพารามิเตอร์ใน CPU และ GPU Tensors Pytorch ของ Speedtorch เพื่อเก็บพารามิเตอร์บน GPU
นี่คือสมุดบันทึกที่ฉันใช้สำหรับการวัดจำนวนหน่วยความจำแต่ละประเภทตัวแปรใช้เวลา https://colab.research.google.com/drive/1zky7pyupaidrnx2hdtbujwo8juy0xkue หากใช้สิ่งนี้ใน colab คุณจะต้องรีสตาร์ทสภาพแวดล้อมหลังจากการสร้างเทนเซอร์แต่ละครั้ง
สำหรับการถ่ายโอน CPU <-> GPU นั้นขึ้นอยู่กับปริมาณของข้อมูลที่ถูกถ่ายโอนและจำนวนแกนที่คุณมี โดยทั่วไปสำหรับ 1-2 CPU cores Speedtorch จะเร็วขึ้นมาก แต่เมื่อจำนวนคอร์ CPU เพิ่มขึ้น CPU ของ Pytorch <-> การดำเนินการดัชนี GPU จะมีประสิทธิภาพมากขึ้น สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้โปรดดูส่วน 'วิธีการทำงาน' ถัดไป สำหรับวิธีง่ายๆในการดูว่าคุณได้รับประโยชน์จากความเร็วในระบบของคุณหรือไม่โปรดเรียกใช้รหัสการเปรียบเทียบในระบบของคุณ แต่เปลี่ยนจำนวนข้อมูลเพื่อสะท้อนจำนวนเงินที่คุณจะทำงานด้วยในแอปพลิเคชันของคุณ
สำหรับการถ่ายโอน GPU <-> GPU หากใช้สัญลักษณ์การจัดทำดัชนีทั่วไปใน Vanilla Pytorch ระบบทั้งหมดจะได้รับความเร็วเพิ่มขึ้นเนื่องจาก Speedtorch บายพาสข้อผิดพลาดในการดำเนินการดัชนีของ Pytorch แต่ข้อผิดพลาดนี้สามารถหลีกเลี่ยงได้หากใช้เวอร์ชันทุกคืนหรือเพียงแค่ใช้แนวคิดการทำดัชนีที่แตกต่างกันโปรดดูส่วน 'วิธีการทำงาน' สำหรับรายละเอียดเพิ่มเติม
อัปเดต 9-20-19: ตอนแรกฉันไม่รู้ว่าทำไมสิ่งนี้เร็วกว่าการใช้ Pytorch Tensors; ฉันสะดุดกับความได้เปรียบความเร็วโดยบังเอิญ แต่หนึ่งในนักพัฒนา Pytorch ในฟอรัม Pytorch ชี้ให้เห็น
สำหรับการถ่ายโอน CPU ที่ดีขึ้น <-> GPU นั้นเป็นเพราะ Speedtorch หลีกเลี่ยงการดำเนินการดัชนี CPU โดยการปิดบัง CPU Tensors เป็น Tensors GPU การดำเนินการดัชนี CPU อาจช้าหากทำงานกับคอร์ CPU น้อยมากเช่น 2 ใน Google Colab แต่อาจเร็วกว่านี้หากคุณมีคอร์จำนวนมาก ขึ้นอยู่กับจำนวนข้อมูลที่คุณถ่ายโอนและจำนวนแกนที่คุณมี
สำหรับการถ่ายโอน GPU ที่ดีกว่า <-> GPU นั้นเป็นเพราะ Speedtorch หลีกเลี่ยงข้อผิดพลาดในการดำเนินการจัดทำดัชนี ข้อผิดพลาดนี้สามารถหลีกเลี่ยงได้โดยใช้การสร้างยามค่ำคืนหรือใช้ index_select / index_copy_ แทนสัญกรณ์ a[idx] ใน 1.1 / 1.2
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเรื่องนี้โปรดดูโพสต์ pytorch นี้
https://discuss.pytorch.org/t/introducing-speedtorch-4x-speed-cpu-gpu-transfer-110x-gpu-cpu-transfer/56147/2
ในกรณีที่วิศวกร Pytorch ให้การวิเคราะห์โดยละเอียดเกี่ยวกับวิธีการจัดดัชนี cupy kernals ส่งผลให้ความเร็วเพิ่มขึ้นในบางกรณี มันไม่ใช่การถ่ายโอนที่เริ่มเร็วขึ้น แต่การจัดทำดัชนี kernals ที่ใช้
สำหรับวิธีการจัดการหน่วยความจำใน Cupy Works ฉันตรงไปที่คำถาม Stackoverflow ทั้งสองนี้ที่ฉันถามซึ่งผู้ใช้ Robert Crovella ที่ยอดเยี่ยมไม่เพียง แต่ให้คำอธิบายโดยละเอียด แต่ยังหาวิธีจัดสรรหน่วยความจำที่ตรึงไว้กับอาร์เรย์ Cupy โดยการพัฒนาหน่วยความจำของเขาสำหรับ Cupy นี่คือเทคโนโลยีหลักที่อยู่เบื้องหลัง Speedtorch
https://stackoverflow.com/questions/57750125/cupy-outofmemoryerror-when-trying-to-cupy-load-larger-dimension-npy-files-in-me
https://stackoverflow.com/questions/57752516/how-to-use-suda-pinned-zero-copy-memory-for-a-memory-mapped-file
Speedtorch สามารถติดตั้งได้ PIP คุณต้องติดตั้งและนำเข้าอย่างถ้วยก่อนที่จะนำเข้า Speedtorch
!pip install SpeedTorch
import cupy
import SpeedTorch
โน๊ตบุ๊ค colab นี้แสดงวิธีการโหลดข้อมูลลงใน Speedtorch โดยใช้แกดเจ็ตข้อมูลและวิธีการถ่ายโอนข้อมูลนี้ไปยัง/จากตัวแปร pytorch cuda
https://colab.research.google.com/drive/185z5gi62azxh-eemfrttjqxeifhobxxf
โปรดดูสมุดบันทึกการเปรียบเทียบความเร็วเพื่อดูความได้เปรียบความเร็วของการใช้ Speedtorch
สำหรับคนแรกที่พยายามหาวิธีใช้ Speedtorch ฉันขอแนะนำให้ติดตามตัวอย่างนี้เนื่องจาก Word2vec เป็นหนึ่งในอัลกอริทึมที่รู้จักกันทั่วไปในการเรียนรู้ของเครื่อง
https://colab.research.google.com/drive/1apjr3onbgqwm3fbcbkmvwagxidxldxot
โน้ตบุ๊กแสดงวิธีฝึก Word2vec วิธีปกติจากนั้นแสดงวิธีการใช้ Speedtorch เพื่อฝึกอบรมข้อมูลเดียวกันโดยใช้หนึ่งในตัวเพิ่มประสิทธิภาพที่ไม่ได้รับการสนับสนุนสำหรับการฝึกอบรมแบบเบาบาง สิ่งนี้เป็นไปได้เพราะเนื่องจากการฝังตัวทั้งหมดที่มีอยู่ในตัวแปรฝังมีการอัปเดตในแต่ละขั้นตอนคุณสามารถตั้งค่า sparse=False ในระหว่างการเริ่มต้น
tl; dr:
การฝึกอบรมปกติ : Pytorch ตัวแปรฝังตัวมีการฝังทั้งหมด Pytorch Optimizer มีน้ำหนักพารามิเตอร์ที่สอดคล้องกันทั้งหมดสำหรับการฝังแต่ละครั้ง
Speedtorch Traing : Pytorch Embeddng ตัวแปรเท่านั้นที่มีชุดของการฝังตัวเท่านั้น Pytorch Optimizer มีน้ำหนักพารามิเตอร์ที่สอดคล้องกันทั้งหมดสำหรับชุดนั้นเท่านั้น Tensors Sparsetorch มีส่วนที่เหลือและแลกเปลี่ยนการฝัง/น้ำหนักด้วยตัวแปร pytorch ในแต่ละขั้นตอน
ในอัลกอริทึมการฝึกอบรมแบบเบาบางเช่น Word2vec, Glove หรือการกรองการทำงานร่วมกันของระบบประสาทมีเพียงเศษเสี้ยวของพารามิเตอร์ทั้งหมด (Embeddngs) เท่านั้นที่ได้รับการฝึกอบรมในทุกขั้นตอน หาก GPU ของคุณไม่สามารถจัดการกับการฝังตัวทั้งหมดของคุณในขนาดฝังที่ต้องการตัวเลือกจะเป็นโฮสต์พารามิเตอร์บางอย่างของคุณในอาร์เรย์ CPU CPU ที่ตรึงและถ่ายโอนพารามิเตอร์เหล่านั้นไปยังเทนเซอร์โมเดลของคุณตามต้องการ การทำสิ่งนี้ใน pytorch จะช้ามากโดยเฉพาะอย่างยิ่งเนื่องจากการถ่ายโอนพารามิเตอร์ระหว่างตัวแปร pytorch ที่ติดตั้ง CUDA และ CPU Pytorch Tensor ที่ติดตั้งอาจใช้เวลา 2.5-3 วินาที (บน Google Colab) โชคดีที่ขั้นตอนนี้ใช้เวลาเพียง 0.02-0.03 วินาทีด้วย Speedtorch!
ใช้กรณี:
-2,829,853 Book Embeddings-
Speedtorch ใช้ในการฝึกอบรมหนังสือ 2,829,853 เล่มสำหรับผู้แนะนำหนังสือหายาก
https://github.com/santosh-gupta/lit2Vec2
https://devpost.com/software/lit2vec2
หนังสือแต่ละเล่มมีการฝังขนาด 400 แต่ขนาดการฝังของ 496 สามารถใช้งานได้ขนาดการฝัง 400 ครั้งนั้นเกิดจากขีด จำกัด ของพื้นที่บน Google ไดรฟ์ของฉันเพื่อจัดเก็บการฝังตัวที่ผ่านการฝึกอบรมมาแล้ว :(
หมายเหตุ: คุณต้องใช้โน้ตบุ๊ก colab เวอร์ชันที่มี RAM 25 GB แทนที่จะเป็น 12 GB ปกติ ในการรับอินสแตนซ์ประเภทนี้คุณจะต้องขัดอินสแตนซ์ปัจจุบันของคุณเนื่องจาก RAM ที่ล้นหลามจากนั้นโน้ตที่มุมล่างซ้ายเพื่อถามว่าคุณต้องการอัพเกรดหรือไม่ คุณสามารถทำได้โดยการทำลูปที่ช่วยเพิ่มขนาดของเมทริกซ์ลอยตัวเป็นสองเท่า
https://colab.research.google.com/drive/1aqht-hetihxmet1wjqrorc3q9tfjqj19
นี่คือลิงค์โดยตรงกับรุ่นและข้อมูลเดียวกัน แต่ไม่ได้ใช้ speedtorch
https://colab.research.google.com/drive/1idv1jbouzvpcfdsy40wirrphedoanti_
การใช้วิธีการฝึกอบรมออร์โธดอกซ์ขนาดการฝังที่ใหญ่ที่สุดที่ colab สามารถจัดการได้คือ 255-260 สูงกว่านั้นและข้อผิดพลาด CUDA จะเกิดขึ้น
RuntimeError: CUDA out of memory. Tried to allocate 2.74 GiB (GPU 0; 11.17 GiB total capacity; 8.22 GiB already allocated; 2.62 GiB free; 5.05 MiB cached)
-14,886,544 รายงานการวิจัย-งานวิจัย-
https://github.com/santosh-gupta/research2vec2
Speedtorch สามารถอนุญาตให้ฉันฝึกอบรม 14,886,544 งานวิจัยการวิจัยที่ฝังขนาด 188 โดยอนุญาตให้ฉันเก็บเป้าหมายการฝังเป้าหมายของฉันไว้ใน CPU ในขณะที่รักษาบริบทของฉันไว้ใน GPU (ใช้เครื่องมือเพิ่มประสิทธิภาพ SGD
นี่คือลิงค์โดยตรงไปยังสมุดบันทึก
https://colab.research.google.com/drive/1sakzsahoy6o_u1df_z15_qkr5ylni_gr
หมายเหตุ: คุณต้องใช้โน้ตบุ๊ก colab เวอร์ชันที่มี RAM 25 GB แทนที่จะเป็น 12 GB ปกติ ในการรับอินสแตนซ์ประเภทนี้คุณจะต้องขัดอินสแตนซ์ปัจจุบันของคุณเนื่องจาก RAM ที่ล้นหลามจากนั้นโน้ตที่มุมล่างซ้ายเพื่อถามว่าคุณต้องการอัพเกรดหรือไม่ คุณสามารถทำได้โดยการทำลูปที่ช่วยเพิ่มขนาดของเมทริกซ์ลอยตัวเป็นสองเท่า
หากไม่มี speedtorch เพียงขนาดการฝังของ 94-96 สามารถใช้กับ Google Colab Tesla K80 GPU ก่อนที่จะ RuntimeError: CUDA out of memory นี่คือเวอร์ชันของการฝึกอบรมโดยไม่ต้องใช้ Speedtorch
https://colab.research.google.com/drive/1jh7rugeajhdwdgnfwg3twm1zjytqu0kr
เมื่อใดก็ตามที่ใช้เทนเซอร์ Cupy GPU ให้เริ่มต้นสิ่งเหล่านี้ก่อนที่จะมีเทนเซอร์ CPU ที่ถูกตรึงไว้ นี่เป็นเพราะการเริ่มต้นของเทนเซอร์ GPU Cupy ดูเหมือนจะใช้ CPU RAM ในปริมาณที่ดี ดังนั้นหากคุณมีข้อ จำกัด ใน CPU RAM และคุณมี CPU Tensors ที่ถูกตรึงไว้ในหน่วยความจำแล้วการเริ่มต้น Tensors GPU Cupy อาจทำให้เกิดความผิดพลาด
หากคุณสามารถพอดีกับพารามิเตอร์ทั้งหมดของคุณในหน่วยความจำ GPU ของคุณให้ใช้ pytorch บริสุทธิ์เนื่องจากนี่เป็นตัวเลือกที่เร็วที่สุดสำหรับการฝึกอบรม แต่ถ้าคุณไม่สามารถพอดีกับพารามิเตอร์ทั้งหมดของคุณในหน่วยความจำให้แยกพารามิเตอร์ของคุณ (โปรดจำไว้ว่าตัวเพิ่มประสิทธิภาพของคุณยังมีน้ำหนัก) ระหว่าง CUDA Tensors CUDA ของ Speedtorch และ CPU Tensors ของ Speedtorch นี่คือตัวเลือกที่เร็วที่สุดที่ 2 แต่ถ้าคุณยังไม่สามารถใส่พารามิเตอร์ทั้งหมดของคุณลงในหน่วยความจำได้ด้วยวิธีนั้นให้แยกพารามิเตอร์ของคุณระหว่าง CPU Tensors CPU ที่ตรึงของ Speedtorch และ Pytorch Cuda Tensors ของ Speedtorch; ช้ากว่าทั้งสองตัวเลือก แต่ใช้หน่วยความจำ GPU น้อยลง สำหรับตัวเลือกที่ 3 นี่คือโน้ตบุ๊กสองเล่มซึ่งแสดงตัวอย่างของ https://colab.research.google.com/drive/1aqht-hetihxmet1wjqrorc3q9tfjqj19 https://colab.research.google.com/drive/1sakzsahoy6o_u1df_z15_qkr5ylni_gr
หลังจากการฝึกอบรมการประหยัดตัวแปร cuda ใด ๆ จะทำให้การใช้หน่วยความจำเพิ่มขึ้นและอาจทำให้เกิดความผิดพลาดโดยเฉพาะอย่างยิ่งกับ cupy หากคุณอยู่ในขอบเขตของแรมของคุณ ในกรณีนี้ให้ใช้วิธี getNumpyVersion เพื่อรับเทนเซอร์รุ่น NumPy ของคุณจากนั้นใช้ numpy.save หรือ hdpy/pytables เพื่อบันทึกอาร์เรย์ numpy ของคุณ Numpy Save มีน้ำหนักเบากว่า
เปิดปัญหาหรือแชทกับฉันไดเรกทอรีบน Gitter ที่นี่ https://gitter.im/speedtorch
ฉันกำลังมองหาฟังก์ชั่นการใช้งานมากขึ้นรอบ CPU ที่รวดเร็ว -> การถ่ายโอน GPU หากคุณมีความคิดโปรดโพสต์ปัญหา GitHub
นอกจากนี้ CPU/CPU ที่ตรึงและ Pytorch GPU Tensors, Speedtorch ยังมี Pytorch ตรึง CPU Tensors และ CPU GPU/CPU Tensors ฉันไม่พบการใช้งานที่ดีสำหรับเทนเซอร์ประเภทเหล่านี้ แต่พวกเขามีรหัสเต็มและใช้งานได้สำหรับการใช้งาน
https://github.com/santosh-gupta/speedtorch/tree/master/speedtorch
พื้นที่หนึ่งที่ฉันต้องการดูคือถ้ามีวิธีลดหน่วยความจำ RAM โดยใช้ memmaps cupy จนถึงตอนนี้พวกเขาใช้ความทรงจำมากเท่ากับเวอร์ชันสด
ModelFactory ( model_variable , total_classes , embed_dimension , datatype = 'float32' , CPUPinn = False )สร้างสวิตช์สำหรับตัวแปรรุ่นโดยใช้ Cupy สวิตช์ตัวแปรจากคอลเลกชันฝังเต็มและคอลเลกชันชุดโมเดลของคุณ ตัวแปรแต่ละตัวต้องการสวิตช์ของตัวเอง
ตัวอย่าง:
uEmbed_switcher = SpeedTorch . ModelFactory ( skip_gram_modelSparse . u_embeddings , total_classes = 50000 , embed_dimension = 128 )ข้อโต้แย้ง:
model_variable : ตัวแปรเฉพาะจากโมเดลของคุณคุณต้องการสร้างสวิตช์สำหรับ
total_classes : จำนวนเงินทั้งหมดของการฝึกอบรมที่จะได้รับการฝึกอบรม
embed_dimension : มิติของ EMBEDDINGS
datatype (ไม่บังคับ): ข้อมูลสำหรับตัวแปร ค่าเริ่มต้นคือ 'float32'
CPUPinn (ไม่บังคับ): ปักหมุดคอลเลกชันฝังเต็มของคุณไปที่ CPU อะไหล่หน่วยความจำ GPU แต่การถ่ายโอนข้อมูลจะช้าลง ค่าเริ่มต้นเป็นเท็จ
วิธีการ:
zerosInit() : เริ่มต้นคอลเลกชันตัวแปรแบบเต็มด้วยศูนย์:
uniformDistributionInit(low, high) : เริ่มต้นคอลเลกชันตัวแปรแบบเต็มรูปแบบพร้อมการแจกแจงแบบสม่ำเสมอจาก low ถึง high
normalDistributionInit(mean, stdDev) : เริ่มต้นตัวแปรสวิตช์คอลเล็กชันเต็มด้วยการแจกแจงปกติด้วยค่าเฉลี่ยของ mean และค่าเบี่ยงเบนมาตรฐานของ stdDev
variableTransformer( batchSize, posPerBatch, negPerBatch = None ) : ตั้งค่าอินพุตจำลองที่จะใช้สำหรับขั้นตอนไปข้างหน้าของโมเดลของคุณ batchSize เป็นขนาดของแบทช์ของคุณและ posPerBatch คือจำนวนตัวอย่างบวกต่อชุด หากจำเป็นต้องใช้อินพุตดัมมี่ที่สองสำหรับตัวอย่างเชิงลบ negPerBatch (ไม่บังคับ) สามารถตั้งค่าเป็นจำนวนตัวอย่างลบและอินพุตจำลองสองตัวจะถูกส่งคืนแทนหนึ่ง
beforeForwardPass(retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์ฝังตัวจากคอลเลกชัน Embeddings แบบเต็มไปยัง Embeddings แบบจำลองของคุณ retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่จะเรียกคืน หากตัวอย่างเชิงลบจะถูกเรียกคืนเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
afterOptimizerStep( retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์ที่อัปเดตจากโมเดลของคุณไปยังคอลเลกชัน Embeddings แบบเต็ม retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่เรียกคืน หากมีการดึงตัวอย่างเชิงลบเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
saveCupy(saveFileName) : บันทึก Tensor เป็น. NPY ไฟล์
loadCupy(loadFileName) : โหลดเทนเซอร์จากไฟล์. npy
getNumpyVersion : รับรุ่นเทนเซอร์ Numpy
OptimizerFactory( given_optimizer, total_classes, embed_dimension, model, variable_name, dtype='float32' , CPUPinn = False)
สร้างสวิตช์สำหรับตัวแปร Optimizer โดยใช้ Cupy สวิตช์ตัวแปรจากคอลเลกชันฝังเต็มและคอลเลกชันชุดเครื่องมือเพิ่มประสิทธิภาพของคุณ ตัวแปรแต่ละตัวต้องการสวิตช์ของตัวเอง
ตัวอย่าง:
uAdagrad_switcher = SpeedTorch . OptimizerFactory ( given_optimizer , total_classes , embed_dimension , model , variable_name , dtype = 'float32' , CPUPinn = False )ข้อโต้แย้ง:
given_optimizer : เครื่องมือเพิ่มประสิทธิภาพเริ่มต้นด้วยน้ำหนักรุ่นของคุณ หากใช้สำหรับการฝึกอบรม Embeddings อย่าลืมตั้งค่าพารามิเตอร์ sparse เป็น False ปัจจุบัน Optimizers ที่รองรับ ได้แก่ Sparseadam, Adadelta, Adamax, Adam, Adamw, ASGD และ RMSPROP RPROP ยังได้รับการยอมรับ แต่ต้องการผ่านไปข้างหน้าครั้งแรกและขั้นตอน loss.backward() เพื่อให้เสร็จสมบูรณ์สำหรับการเริ่มต้นอินสแตนซ์ OptimizerFactory นี่เป็นเพราะ RPROP เพิ่มประสิทธิภาพที่ต้องการการไล่ระดับสีของพารามิเตอร์สำหรับการเริ่มต้น
total_classes : จำนวนเงินทั้งหมดของการฝึกอบรมที่จะได้รับการฝึกอบรม
embed_dimension : มิติของ EMBEDDINGS
model : อินสแตนซ์ของโมเดลของคุณ
variable_name : ชื่อที่แน่นอนของตัวแปรที่กำหนดไว้ในโมเดลของคุณ
dtype (ไม่บังคับ): ประเภทข้อมูลของตัวแปรของคุณ ค่าเริ่มต้นคือ 'float32'
CPUPinn (ไม่บังคับ): ปักหมุดการรวบรวมน้ำหนักตัวแปรออพท์เซอร์เต็มรูปแบบของคุณเป็น CPU อะไหล่หน่วยความจำ GPU แต่การถ่ายโอนข้อมูลจะช้าลง ค่าเริ่มต้นเป็นเท็จ
วิธีการ:
optInit : เริ่มต้นสวิตช์ตัวแปร Optimizer
beforeForwardPass(retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์น้ำหนักตัวแปรออปชั่นจากคอลเลกชันน้ำหนักเต็มไปจนถึงเทนเซอร์น้ำหนักเพิ่มประสิทธิภาพ retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่จะเรียกคืน หากตัวอย่างเชิงลบจะถูกเรียกคืนเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
afterOptimizerStep( retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์น้ำหนักตัวแปรตัวแปรจากเครื่องมือเพิ่มประสิทธิภาพของคุณไปยังคอลเลกชันน้ำหนักเต็ม retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่เรียกคืน หากมีการดึงตัวอย่างเชิงลบเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
สร้างเทนเซอร์ที่มีฟังก์ชั่นหลักคือการถ่ายโอนเนื้อหาของมันไปยังตัวแปร pytorch cuda
DataGadget( fileName, CPUPinn=False)
ข้อโต้แย้ง:
fileName : ตำแหน่งของข้อมูล. npy ไฟล์ที่จะเปิด
CPUPinn : (ไม่บังคับ): ปักข้อมูลของคุณเป็น CPU ค่าเริ่มต้นเป็นเท็จ
วิธีการ:
getData(indexes) : ดึงข้อมูลในรูปแบบที่พร้อมที่จะได้รับการยอมรับโดยตัวแปร pytorch cuda indexes เป็นดัชนีของเทนเซอร์ที่จะดึงข้อมูลจาก
insertData(dataObject, indexes) : แทรกข้อมูลจากตัวแปร Pytorch Cuda dataObject เป็นข้อมูลเทนเซอร์ตัวแปร Pytorch CUDA ซึ่งข้อมูลจะถูกดึงมาจากและ indexes ของเทนเซอร์ที่จะดึงข้อมูลจาก
saveCupy(saveFileName) : บันทึก Tensor เป็น. NPY ไฟล์
loadCupy(loadFileName) : โหลดเทนเซอร์ใหม่จากไฟล์. npy
getNumpyVersion : รับรุ่นเทนเซอร์ Numpy
โปรดดูสมุดบันทึกนี้เกี่ยวกับวิธีการใช้แกดเจ็ตข้อมูล
https://colab.research.google.com/drive/185z5gi62azxh-eemfrttjqxeifhobxxf
PytorchModelFactory ( model_variable , total_classes , embed_dimension , datatype = 'float32' , deviceType = 'cuda' , pinType = False )สร้างสวิตช์สำหรับตัวแปรโมเดลโดยใช้ Pytorch Tensors สวิตช์ตัวแปรจากคอลเลกชันฝังเต็มและคอลเลกชันชุดโมเดลของคุณ ตัวแปรแต่ละตัวต้องการสวิตช์ของตัวเอง
ตัวอย่าง:
uEmbed_switcher = SpeedTorch . PytorchModelFactory ( skip_gram_modelSparse . u_embeddings , total_classes = 50000 , embed_dimension = 128 )ข้อโต้แย้ง:
model_variable : ตัวแปรเฉพาะจากโมเดลของคุณคุณต้องการสร้างสวิตช์สำหรับ
total_classes : จำนวนเงินทั้งหมดของการฝึกอบรมที่จะได้รับการฝึกอบรม
embed_dimension : มิติของ EMBEDDINGS
datatype (ไม่บังคับ): ข้อมูลสำหรับตัวแปร ค่าเริ่มต้นคือ 'float32'
deviceType (ไม่บังคับ): ตั้งค่าอุปกรณ์เป็น 'cuda' หรือ 'CPU' ค่าเริ่มต้นคือ 'cuda'
pinType (ไม่บังคับ): หากอุปกรณ์ถูกตั้งค่าเป็น 'CPU' คุณสามารถระบุโดยใช้หน่วยความจำที่ตรึง ค่าเริ่มต้นคือ 'เท็จ'
วิธีการ:
zerosInit() : เริ่มต้นคอลเลกชันตัวแปรแบบเต็มด้วยศูนย์:
uniformDistributionInit(low, high) : เริ่มต้นคอลเลกชันตัวแปรแบบเต็มรูปแบบพร้อมการแจกแจงแบบสม่ำเสมอจาก low ถึง high
normalDistributionInit(mean, stdDev) : เริ่มต้นตัวแปรสวิตช์คอลเล็กชันเต็มด้วยการแจกแจงปกติด้วยค่าเฉลี่ยของ mean และค่าเบี่ยงเบนมาตรฐานของ stdDev
customInit(initFunction, *args) : ใช้ pytorch initializer ใด ๆ สำหรับตัวแปร switchers คอลเลกชันเต็ม ผ่านการเริ่มต้นโดยใช้ initFunction และอาร์กิวเมนต์ที่สอดคล้องกันโดยใช้ *args
variableTransformer(batchSize, posPerBatch, negPerBatch = None ) : ตั้งค่าอินพุตจำลองที่จะใช้สำหรับขั้นตอนไปข้างหน้าของโมเดลของคุณ batchSize เป็นขนาดของแบทช์ของคุณและ posPerBatch คือจำนวนตัวอย่างบวกต่อชุด หากจำเป็นต้องมีอินพุตดัมมี่ที่สองสำหรับตัวอย่างเชิงลบ negPerBatch (ไม่บังคับ) สามารถตั้งค่าเป็นจำนวนตัวอย่างลบและอินพุตจำลองสองตัวจะถูกส่งคืนแทนหนึ่ง
beforeForwardPass(retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์ฝังตัวจากคอลเลกชัน Embeddings แบบเต็มไปยัง Embeddings แบบจำลองของคุณ retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่จะเรียกคืน หากตัวอย่างเชิงลบจะถูกเรียกคืนเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
afterOptimizerStep(retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์ที่อัปเดตจากโมเดลของคุณไปยังคอลเลกชัน Embeddings แบบเต็ม retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่เรียกคืน หากมีการดึงตัวอย่างเชิงลบเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
saveTorch(saveFileName) : บันทึกเทนเซอร์ไปยังไฟล์โดยใช้ Torch.save
loadTorch(loadFileName) : โหลดเทนเซอร์โดยใช้ Torch.load
getNumpyVersion : รับรุ่นเทนเซอร์ Numpy
PytorchOptimizerFactory( given_optimizer, total_classes, embed_dimension, model, variable_name, dtype='float32', deviceType = 'cuda', pinType = False)
สร้างสวิตช์สำหรับตัวแปร Optimizer โดยใช้ Pytorch Tensors สวิตช์ตัวแปรจากคอลเลกชันฝังเต็มและคอลเลกชันชุดเครื่องมือเพิ่มประสิทธิภาพของคุณ ตัวแปรแต่ละตัวต้องการสวิตช์ของตัวเอง
ตัวอย่าง:
uAdagrad_switcher = SpeedTorch . PytorchOptimizerFactory ( given_optimizer , total_classes , embed_dimension , model , variable_name , dtype = 'float32' )ข้อโต้แย้ง:
given_optimizer : เครื่องมือเพิ่มประสิทธิภาพเริ่มต้นด้วยน้ำหนักรุ่นของคุณ หากใช้สำหรับการฝึกอบรม Embeddings อย่าลืมตั้งค่าพารามิเตอร์ sparse เป็น False ปัจจุบัน Optimizers ที่รองรับ ได้แก่ Sparseadam, Adadelta, Adamax, Adam, Adamw, ASGD และ RMSPROP RPROP ยังได้รับการยอมรับ แต่ต้องการผ่านไปข้างหน้าครั้งแรกและขั้นตอน loss.backward() เพื่อให้เสร็จสมบูรณ์สำหรับการเริ่มต้นอินสแตนซ์ OptimizerFactory นี่เป็นเพราะ RPROP เพิ่มประสิทธิภาพที่ต้องการการไล่ระดับสีของพารามิเตอร์สำหรับการเริ่มต้น
total_classes : จำนวนเงินทั้งหมดของการฝึกอบรมที่จะได้รับการฝึกอบรม
embed_dimension : มิติของ EMBEDDINGS
model : อินสแตนซ์ของโมเดลของคุณ
variable_name : ชื่อที่แน่นอนของตัวแปรที่กำหนดไว้ในโมเดลของคุณ
dtype (ไม่บังคับ): ประเภทข้อมูลของตัวแปรของคุณ ค่าเริ่มต้นคือ 'float32'
deviceType (ไม่บังคับ): ตั้งค่าอุปกรณ์เป็น 'cuda' หรือ 'CPU' ค่าเริ่มต้นคือ 'cuda'
pinType (ไม่บังคับ): หากอุปกรณ์ถูกตั้งค่าเป็น 'CPU' คุณสามารถระบุโดยใช้หน่วยความจำที่ตรึง ค่าเริ่มต้นคือ 'เท็จ'
วิธีการ:
optInit : เริ่มต้นสวิตช์ตัวแปร Optimizer
beforeForwardPass(retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์น้ำหนักตัวแปรออปชั่นจากคอลเลกชันน้ำหนักเต็มไปจนถึงเทนเซอร์น้ำหนักเพิ่มประสิทธิภาพ retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่จะเรียกคืน หากตัวอย่างเชิงลบจะถูกเรียกคืนเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
afterOptimizerStep( retrievedPosIndexes , retrievedNegIndexes = None) : สวิตช์น้ำหนักตัวแปรตัวแปรจากเครื่องมือเพิ่มประสิทธิภาพของคุณไปยังคอลเลกชันน้ำหนักเต็ม retrievedPosIndexes เป็นดัชนีของตัวอย่างบวกที่เรียกคืน หากมีการดึงตัวอย่างเชิงลบเช่นกันค่าสำหรับ retrievedNegIndexes (ไม่บังคับ) สามารถส่งผ่านได้เช่นกัน
หากคุณใช้ speedtorch ในการวิจัยของคุณหรือต้องการอ้างอิงโปรดอ้างอิงกับ:
@misc {
title = {speedtorch}
ผู้แต่ง = {Santosh Gupta}
Howpublished = { url {github.com/santosh-gupta/speedtorch}}
ปี = {2019}
-