Jupyter Lab หยุดการทำงานของคอมพิวเตอร์เมื่อไม่มีแรม - จะป้องกันได้อย่างไร?


12

ฉันเพิ่งเริ่มใช้ Jupyter Lab และปัญหาของฉันคือฉันทำงานกับชุดข้อมูลที่มีขนาดใหญ่มาก (โดยปกติชุดข้อมูลนั้นจะมีขนาดประมาณ 1/4 ของ RAM คอมพิวเตอร์ของฉัน) หลังจากการเปลี่ยนแปลงเล็กน้อยบันทึกเป็นวัตถุ Python ใหม่ฉันมักจะมีหน่วยความจำไม่เพียงพอ ปัญหาคือเมื่อฉันใกล้จะถึงขีด จำกัด RAM ที่มีอยู่และดำเนินการใด ๆ ที่ต้องการพื้นที่แรมอื่นคอมพิวเตอร์ของฉันค้างและวิธีเดียวที่จะแก้ไขมันคือการรีสตาร์ทมัน นี่เป็นพฤติกรรมเริ่มต้นใน Jupyter Lab / Notebook หรือเป็นการตั้งค่าบางอย่างที่ฉันควรตั้งค่า? โดยปกติฉันคาดหวังว่าโปรแกรมจะพัง (เช่นใน RStudio เป็นต้น) ไม่ใช่คอมพิวเตอร์ทั้งหมด


ฉันมีปัญหาเดียวกันก่อนหน้านี้มันน่ารังเกียจจริงๆ ฉันได้ดูอย่างรวดเร็วในปัญหาจูปีเตอร์และไม่พบอะไรเลย มันจะเกิดขึ้นเช่นกันถ้าคุณเรียกใช้ผ่านคอนโซล IPython (ไม่ใช่แบบหลามธรรมดา) หรือไม่
Bzazz

คุณใช้แพ็คเกจ / โมดูลอะไร มันคือระบบปฏิบัติการอะไร? คุณมี swap หรือไม่ Jupyter Lab รุ่นใด ถ้าเป็นลินุกซ์แล้วเคอร์เนลจะเป็นเวอร์ชั่นอะไร?
Nizam Mohamed

ส่วนใหญ่เป็นหมีแพนด้า แต่ฉันไม่คิดว่ามันเกี่ยวข้องกับแพ็คเกจ ระบบปฏิบัติการคือ Ubuntu 16.04.6 LTS และรุ่นเคอร์เนลคือ 4.15.0-65-generic รุ่น Jupyter Lab คือ 1.0.2 ฉันมี SWAP ตั้งไว้ที่ 12 GB (กำหนดให้กับ 2 ไฟล์) ซึ่งเป็น 1.5 RAM ของฉัน
jakes

คำตอบ:


5

ทางออกที่ดีที่สุดสำหรับปัญหานี้คือการใช้ตู้คอนเทนเนอร์ Docker คุณสามารถระบุจำนวนหน่วยความจำที่จะจัดสรรให้กับ Jupyter และถ้าคอนเทนเนอร์หมดหน่วยความจำมันก็ไม่ใช่เรื่องใหญ่ (เพียงจำไว้ว่าให้บันทึกบ่อยครั้ง แต่จะไปโดยไม่พูดอะไร)

บล็อกนี้จะช่วยให้คุณได้รับประโยชน์สูงสุดจากที่นั่น นอกจากนี้ยังมีคำแนะนำที่เหมาะสมในการตั้งค่า Jupyter Lab จากรูปภาพ Jupyter ที่มีให้ใช้งานฟรีและได้รับการบำรุงรักษาอย่างเป็นทางการที่นี่:

https://medium.com/fundbox-engineering/overview-d3759e83969c

จากนั้นคุณสามารถแก้ไขdocker runคำสั่งตามที่อธิบายไว้ในบทช่วยสอนเป็น (เช่นสำหรับ 3GB):

docker run --memory 3g <other docker run args from tutorial here>

สำหรับไวยากรณ์ในตัวเลือกหน่วยความจำนักเทียบท่าดูคำถามนี้:

ตัวเลือกนักเทียบท่าเรียกใช้ตัวเลือก "- หน่วยความจำ" อย่างไร


4

หากคุณใช้ Ubuntu ลองดูที่ OOM killers คุณสามารถรับข้อมูลได้จากที่นี่

คุณสามารถใช้ก่อนกำหนด สามารถกำหนดค่าได้ตามที่คุณต้องการเช่นearlyoom -s 90 -m 15จะเริ่มearlyoomและเมื่อขนาดสวอปน้อยกว่า% 90 และหน่วยความจำน้อยกว่า% 15 มันจะฆ่ากระบวนการที่ทำให้ OOM และป้องกันไม่ให้ทั้งระบบหยุดทำงาน นอกจากนี้คุณยังสามารถกำหนดค่าลำดับความสำคัญของกระบวนการ


2

ฉันยังทำงานกับชุดข้อมูลขนาดใหญ่มาก (3GB) ใน Jupyter Lab และประสบปัญหาเดียวกันกับ Labs มันไม่ชัดเจนถ้าคุณต้องการรักษาการเข้าถึงข้อมูลที่แปลงก่อนหน้าถ้าไม่ฉันเริ่มใช้delตัวแปร dataframe ขนาดใหญ่ที่ไม่ได้ใช้ถ้าฉันไม่ต้องการพวกเขา delลบตัวแปรออกจากหน่วยความจำของคุณ แก้ไข **: มีความเป็นไปได้หลายอย่างสำหรับปัญหาที่ฉันพบ ฉันพบสิ่งนี้บ่อยขึ้นเมื่อฉันใช้อินสแตนซ์จูปิเตอร์เตอร์ระยะไกลและในสายลับเช่นกันเมื่อฉันทำการแปลงโฉมครั้งใหญ่

เช่น

df = pd.read('some_giant_dataframe') # or whatever your import is
new_df = my_transform(df)
del df # if unneeded.

ทำให้คุณอาจพบว่าเธรดนี้บนเวิร์กโฟลว์ข้อมูลขนาดใหญ่มีประโยชน์ ฉันดูDaskเพื่อช่วยในการเก็บข้อมูลหน่วยความจำ

ฉันสังเกตเห็นใน spyder และ jupyter ว่าการตรึงมักจะเกิดขึ้นเมื่อทำงานในคอนโซลอื่นในขณะที่หน่วยความจำขนาดใหญ่ทำงาน สำหรับสาเหตุที่มันหยุดทำงานแทนที่จะหยุดทำฉันคิดว่ามันเกี่ยวข้องกับเคอร์เนล มีปัญหาหน่วยความจำสองสามอย่างที่เปิดใน IPith Github - # 10082และ # 10117ดูเหมือนจะเกี่ยวข้องมากที่สุด ผู้ใช้หนึ่งคนที่นี่แนะนำให้ปิดการใช้งานการเติมแท็บในjediหรืออัพเดทเจได

ใน 10117 get_ipython().history_manager.db_log_outputพวกเขาเสนอการตรวจสอบการส่งออกของ ฉันมีปัญหาเดียวกันและการตั้งค่าของฉันถูกต้อง แต่มันก็คุ้มค่าที่จะตรวจสอบ


1

นอกจากนี้คุณยังสามารถใช้โน๊ตบุ๊คในเมฆยังเช่น Google Colab ที่นี่ พวกเขามีสิ่งอำนวยความสะดวกสำหรับ RAM ที่แนะนำและการสนับสนุนสำหรับโน้ตบุ๊ก Jupyter นั้นเป็นค่าเริ่มต้น


0

ฉันคิดว่าคุณควรใช้ชิ้น เช่นนั้น:

df_chunk = pd.read_csv(r'../input/data.csv', chunksize=1000000)
chunk_list = []  # append each chunk df here 

# Each chunk is in df format
for chunk in df_chunk:  
    # perform data filtering 
    chunk_filter = chunk_preprocessing(chunk)

    # Once the data filtering is done, append the chunk to list
    chunk_list.append(chunk_filter)

# concat the list into dataframe 
df_concat = pd.concat(chunk_list)

สำหรับข้อมูลเพิ่มเติมตรวจสอบได้ที่: https://towardsdatascience.com/why-and-how-to-use-pandas-with-large-data-9594dda2ea4c

ฉันขอแนะนำไม่ผนวกรายการอีกครั้ง (อาจ RAM จะโอเวอร์โหลดอีกครั้ง) คุณควรทำงานของคุณให้เสร็จ


ฉันคิดว่าปัญหาที่นี่ไม่ใช่วิธีที่จะไม่ใช้หน่วยความจำไม่เพียงพอ แต่จะหลีกเลี่ยงปัญหาคอมพิวเตอร์หยุดทำงานและต้องรีสตาร์ท Python ควรหยุดทำงานหรือโยน memoryerror แต่ไม่ทำทุกอย่างยุ่ง
Bzazz

0

ฉันจะสรุปคำตอบจากต่อไปนี้คำถาม คุณสามารถ จำกัด การใช้หน่วยความจำของโปรแกรมของคุณ ram_intense_foo()ในต่อไปนี้จะเป็นฟังก์ชั่น ก่อนที่จะโทรคุณต้องโทรไปที่ฟังก์ชั่นlimit_memory(10)

import resource
import platform
import sys
import numpy as np 

def memory_limit(percent_of_free):
    soft, hard = resource.getrlimit(resource.RLIMIT_AS)
    resource.setrlimit(resource.RLIMIT_AS, (get_memory() * 1024 * percent_of_free / 100, hard))

def get_memory():
    with open('/proc/meminfo', 'r') as mem:
        free_memory = 0
        for i in mem:
            sline = i.split()
            if str(sline[0]) == 'MemAvailable:':
                free_memory = int(sline[1])
                break
    return free_memory

def ram_intense_foo(a,b):
    A = np.random.rand(a,b)
    return A.T@A

if __name__ == '__main__':
    memory_limit(95)
    try:
        temp = ram_intense_foo(4000,10000)
        print(temp.shape)
    except MemoryError:
        sys.stderr.write('\n\nERROR: Memory Exception\n')
        sys.exit(1)

-4

ไม่มีเหตุผลที่จะดูผลลัพธ์ทั้งหมดของดาต้าเฟรมขนาดใหญ่ การดูหรือจัดการกับไฟล์ข้อมูลขนาดใหญ่จะใช้ทรัพยากรคอมพิวเตอร์ของคุณจำนวนมากโดยไม่จำเป็น

สิ่งที่คุณกำลังทำสามารถทำได้ในขนาดเล็ก มันทำงานได้ง่ายกว่าในการเขียนโค้ดและจัดการข้อมูลเมื่อเฟรมข้อมูลมีขนาดเล็ก วิธีที่ดีที่สุดในการทำงานกับข้อมูลขนาดใหญ่คือการสร้างกรอบข้อมูลใหม่ที่ใช้เพียงส่วนเล็ก ๆ หรือตัวอย่างเล็ก ๆ ของกรอบข้อมูลขนาดใหญ่ จากนั้นคุณสามารถสำรวจข้อมูลและทำการเข้ารหัสบนเฟรมข้อมูลที่เล็กลง เมื่อคุณสำรวจข้อมูลและทำให้รหัสของคุณใช้งานได้ให้ใช้โค้ดนั้นในกรอบข้อมูลที่ใหญ่ขึ้น

วิธีที่ง่ายที่สุดคือการใช้ n แรกจำนวนแถวแรกจากกรอบข้อมูลโดยใช้ฟังก์ชัน head () ฟังก์ชั่นส่วนหัวพิมพ์เพียง n จำนวนแถว คุณสามารถสร้างกรอบข้อมูลขนาดเล็กได้โดยใช้ฟังก์ชั่นส่วนหัวบนกรอบข้อมูลขนาดใหญ่ ด้านล่างฉันเลือกที่จะเลือก 50 แถวแรกและส่งผ่านค่าไปยัง small_df สิ่งนี้ถือว่า BigData เป็นไฟล์ข้อมูลที่มาจากไลบรารีที่คุณเปิดสำหรับโครงการนี้

library(namedPackage) 

df <- data.frame(BigData)                #  Assign big data to df
small_df <- head(df, 50)         #  Assign the first 50 rows to small_df

สิ่งนี้จะได้ผลเกือบตลอดเวลา แต่บางครั้งกรอบข้อมูลขนาดใหญ่จะมาพร้อมกับตัวแปรที่กำหนดไว้ล่วงหน้า หากข้อมูลขนาดใหญ่เป็นเช่นนี้คุณจะต้องสุ่มตัวอย่างแถวจากข้อมูลขนาดใหญ่ จากนั้นใช้รหัสที่ตามมา:

df <- data.frame(BigData)

set.seed(1016)                                          # set your own seed

df_small <- df[sample(nrow(df),replace=F,size=.03*nrow(df)),]     # samples 3% rows
df_small                                                         # much smaller df
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.