참조 : https://stackoverflow.com/questions/11328958/save-multiple-plots-in-a-single-pdf-file

 

Save multiple plots in a single PDF file

plotting module def plotGraph(X,Y): fignum = random.randint(0,sys.maxint) plt.figure(fignum) ### Plotting arrangements ### return fignum main module import matplotlib.pyplot as plt...

stackoverflow.com

 

with PdfPages('multipage_pdf.pdf') as pdf:
  # 그래프1 
  plt.figure(figsize=(3, 3))
  plt.plot(range(7), [0,1,2,3,4,5,6], 'r-o')
  plt.title('graph one')
  pdf.savefig()  # saves the current figure into a pdf page

  # 그래프2
  plt.figure(figsize=(3, 3))
  plt.plot(range(7), [0,1,2,3,4,5,6], 'r-o')
  plt.title('graph two')
  pdf.savefig()  # saves the current figure into a pdf page
  # plt.close() 그래프 출력안할거면 사용

1. isolation forest 로 정상에 가까운 클러스터, 비정상에 가까운 클러스터 이렇게 두개 묶음 만들기

2.  데이터 train_정상/train_비정상/test_정상/test_비정상 이케 데이터 나눠준다

3. train_정상 만 가지고 lstm autoencoder 학습시키고 테스트 데이터 넣어서 threshold 를 구해준다 

=> 이 스레숄드가 뭐나면? 재구성손실값임. 한마디로 정상치만 가지고 학습시켰을때 똑같이 정상치라면 재구성할떄 오류가 많이 나지않음.스레숄드가 낮게나온다는 뜻임. 그렇다면 정상, 그런데 완전 다른 그림을 학습시킨다면 재구성할때 오차가 엄청날것임. 스레숄드가 엄청 크게 나온다는뜻. 스레숄드보다 높은값이 나온것은 정상이랑 많이 다른양상이라는 뜻이므로 anomaly 로 구분한다.

4. 이렇게 전체 데이터를 집어넣어봐서 스레숄드보다 높은값을 보이면 (재구성손실이 많다면) anomaly 로 라벨링하고, 스레숄드보다 낮은값을 보이면(재구성손실이 적다면, 정상치 트레인데이터와 비슷한양상을 보인다면) 정상값으로 라벨링한다.

스레숄드 구하는법은 아래와같음

** 정밀도 ( precision) : 참이라고 예측한 데이터중 실제로 참인 데이터 

**제현율 ( RECALL ) : 실제로 참인 데이터중에서 참이라고 예측한 데이터

긁어옴)) : 재현율이 높지만 정밀도가 낮다는 것은 찾은 데이터의 수가 많지만 그 중 실제 찾으려는 대상의 비율은 낮았다는 것을 의미합니다. 이와 반대로 정밀도가 높지만 재현율이 낮다는 것은 찾은 데이터의 수는 작지만 그 중 실제 찾으려는 대상의 비율은 높다는 것을 의미합니다. 이상적으로는, 정밀도와 재현율이 모두 높은 것이 좋습니다. 이는 찾은 데이터 수가 많으며 그 중 실제 찾으려는 대상의 비율이 높다는 것을 의미합니다. 그렇기 때문에 threshold 값은 이 정밀도와 재현률이 둘다 좋은지점을 찾아 threshold 라고 정의해줍니다.

 

 

참조 : 

https://www.koreascience.or.kr/article/CFKO202125036427364.pdf (국내학회)

https://towardsdatascience.com/lstm-autoencoder-for-extreme-rare-event-classification-in-keras-ce209a224cfb

https://velog.io/@jaehyeong/LSTM-Autoencoder-for-Anomaly-Detection 

 

 

 

 

 

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import math
from pylab import rcParams
from collections import Counter
import tensorflow as tf
from tensorflow.keras import Model ,models, layers, optimizers, regularizers
from tensorflow.keras.callbacks import ModelCheckpoint
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn import metrics
%matplotlib inline
from sklearn.ensemble import IsolationForest
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from mpl_toolkits.mplot3d import Axes3D
import pickle
import glob
from tensorflow.python.keras.metrics import Metric
import sklearn
# lsmt ae 에서 사용할 함수 
# LSTM 모델은 (samples, timesteps, feature)에 해당하는 3d 차원의 shape을 가지므로, 데이터를 시퀀스 형태로 변환한다.
def temporalize(X, y, timesteps): 
	output_X = []  
	output_y = []
	for i in range(len(X) - timesteps - 1):  
		t = []
		for j in range(1, timesteps + 1):
			# Gather the past records upto the lookback period
			t.append(X[[(i + j + 1)], :])
		output_X.append(t)
		output_y.append(y[i + timesteps + 1])
	return np.squeeze(np.array(output_X)), np.array(output_y)
content={}
#데이터별로 이상치 index를 담아줄 딕셔너리. 마지막에 anomaly라고 라벨링된 index만 뽑아서 "데이터이름" : [1,2,4...] 이런식으로 key,value 값을 저장해줄것.
parameter = [0.01 , 0.015, 0.02, 0.025, 0.03]

for k in filenames:
    for j in parameter:
        print(j)
        df = pd.read_csv(str(k))
        
        
        # 1차 라벨링 부분
        #isolationForest 적용 + 그림으로 보이기 ---------------------------------------------------------
        
        from sklearn.ensemble import IsolationForest
        clf=IsolationForest(n_estimators=50, max_samples=50, contamination = float(j), 
                                max_features=1.0, bootstrap=False, n_jobs=-1, random_state=None, verbose=0)
        clf.fit(df)
        pred = clf.predict(df)
        df['anomaly'] = pred  # isolation forest로 1차 라벨링된것을 새피처로써 추가함.
        outliers = df.loc[df['anomaly'] == -1]
        outlier_index = list(outliers.index) # 1차 라벨링해서 이상치값의 index 만 outlier_index 리스트로 만듬. 
        pca = PCA(n_components = 5) # isolation 적용한후, 피처개수가 너무많아서 차원축소해준다. 

        scaler = StandardScaler()
        X = scaler.fit_transform(df)
        X_reduce = pca.fit_transform(X)
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.scatter(X_reduce[:, 0], X_reduce[:, 1], s=4, lw=1, label="inliers",c="green")
        ax.scatter(X_reduce[outlier_index,0],X_reduce[outlier_index,1],
                   lw=1, s=4, c="red", label="outliers")
        ax.legend()
        plt.show()
        print("isolation forest 적용후값  : " + str(Counter(pred)))
        
         
        # 2차 라벨링 부분 
        # Train/valid data split -------------------------------------------------------------------------------
        
        input_x = X_reduce   # isolation forest 로 1차 라벨링한값을 차원축소한후 lstm ae 의 인풋데이터로 사용할것
        input_y = []
        # 1차 라벨링에서 1 정상 -1 비정상으로 1차 라벨링된값을 => 1 비정상 0 정상으로 숫자만 바꿔줌
        for i in range(len(input_x)):   # 1 , -1
            if i in outlier_index:
                input_y.append(1) # 비정상
            else :
                input_y.append(0) # 정상
        input_y = np.array(input_y)  
        
        timesteps = 3
        x, y = temporalize(input_x, input_y, timesteps)   # LSTM 모델은 (samples, timesteps, feature)에 해당하는 3d 차원의 shape을 가지므로, 데이터를 시퀀스 형태로 변환한다.


        # Split into train and valid
        x_train, x_valid, y_train, y_valid = train_test_split(x, y, test_size=0.2)
        n_features = input_x.shape[1]
        
        # For training the autoencoder, split 0 / 1
        x_train_y0 = x_train[y_train == 0] # 정상데이터 y0
        x_train_y1 = x_train[y_train == 1] # 비정상데이터 y1
        x_valid_y0 = x_valid[y_valid == 0]
        x_valid_y1 = x_valid[y_valid == 1]

        x_y0 = x[y==0] # 정상데이터 y0
        x_y1 = x[y==1] # 비정상데이터 y1
        
        def flatten(X):
            flattened_X = np.empty((X.shape[0], X.shape[2]))  # sample x features array.
            for i in range(X.shape[0]):
                flattened_X[i] = X[i, (X.shape[1]-1), :]
            return(flattened_X)
        def scale(X, scaler):
            for i in range(X.shape[0]):
                X[i, :, :] = scaler.transform(X[i, :, :])  
            return X

        scaler = StandardScaler().fit(flatten(x_train_y0))
        x_train_y0_scaled = scale(x_train_y0, scaler)
        x_valid_scaled = scale(x_valid, scaler)
        x_valid_y0_scaled = scale(x_valid_y0, scaler)
        x_total_scaled = scale(x, scaler)   
        x_y0_sacled = scale(x_y0, scaler)

        # LSTM Autoencoder 적용 -------------------------------------------------------------------------------
        epochs = 5
        batch = 128
        lr = 0.001
        lstm_ae = models.Sequential()
        # Encoder
        lstm_ae.add(layers.LSTM(32, activation='relu', input_shape=(timesteps, n_features), return_sequences=True))
        lstm_ae.add(layers.LSTM(16, activation='relu', return_sequences=False))
        lstm_ae.add(layers.RepeatVector(timesteps))
        # Decoder
        lstm_ae.add(layers.LSTM(16, activation='relu', return_sequences=True))
        lstm_ae.add(layers.LSTM(32, activation='relu', return_sequences=True))
        lstm_ae.add(layers.TimeDistributed(layers.Dense(n_features)))
        # compile
        lstm_ae.compile(loss='mse', optimizer=optimizers.Adam(lr))
        # fit
        history = lstm_ae.fit(x_y0_sacled, x_y0_sacled,
                             epochs=epochs, batch_size=batch,
                             validation_data=(x_valid_y0_scaled, x_valid_y0_scaled))
        
        
        
        # normal/anomaly 를 구분해주는 기준 threshold 를 구함  -------------------------------------------------------

        valid_x_predictions = lstm_ae.predict(x_valid_scaled)
        mse = np.mean(np.power(flatten(x_valid_scaled) - flatten(valid_x_predictions), 2), axis=1)

        error_df = pd.DataFrame({'Reconstruction_error':mse, 
                                 'True_class':list(y_valid)})
        precision_rt, recall_rt, threshold_rt = sklearn.metrics.precision_recall_curve(error_df['True_class'], error_df['Reconstruction_error'])
        
        
        # precision/recall 값
        index_cnt = [cnt for cnt, (p, r) in enumerate(zip(precision_rt, recall_rt)) if p==r][0]
        #print('precision: ',precision_rt[index_cnt],', recall: ',recall_rt[index_cnt])

        # threshold 값
        threshold_fixed = threshold_rt[index_cnt]
        #print('threshold: ',threshold_fixed)


        # threshold 보다 낮으면 정상(normal), 높으면 이상(anomaly)으로 판단한다.
        # 정밀도 ( precision) : 참이라고 예측한 데이터중 실제로 참인 데이터 (참 / 참인데참,거짓인데참)
        # 제햔율 ( RECALL ) : 실제로 참인 데이터중에서 참이라고 예측한 데이터? (참/ 참인데참, 참인데 거짓))

        
        
        # threshold 값을 기준으로 normal/anomlay 인지 라벨링해줌 ----------------------------------------------------------------
        test_x_predictions = lstm_ae.predict(x_total_scaled) 
        mse = np.mean(np.power(flatten(x_total_scaled) - flatten(test_x_predictions), 2), axis=1)
        error_df = pd.DataFrame({'Reconstruction_error': mse,
                                 'True_class': y.tolist()})
        groups = error_df.groupby('True_class')
        fig, ax = plt.subplots()

        for name, group in groups:
            ax.plot(group.index, group.Reconstruction_error, marker='o', ms=3.5, linestyle='',
                    label= "Break" if name == 1 else "Normal")
        ax.hlines(threshold_fixed, ax.get_xlim()[0], ax.get_xlim()[1], colors="r", zorder=100, label='Threshold')
        ax.legend()
        plt.title("Reconstruction error for different classes")
        plt.ylabel("Reconstruction error")
        plt.xlabel("Data point index")
        plt.show();
        
        
        # classification by threshold
        pred_y = [1 if e > threshold_fixed else 0 for e in error_df['Reconstruction_error'].values]
        LABELS = ['Normal', 'Break']
        conf_matrix = sklearn.metrics.confusion_matrix(error_df['True_class'], pred_y)
        plt.figure(figsize=(7, 7))
        sns.heatmap(conf_matrix, xticklabels=LABELS, yticklabels=LABELS, annot=True, fmt='d')
        plt.title('Confusion Matrix')
        plt.xlabel('Predicted Class'); plt.ylabel('True Class')
        plt.show()


        # TN/FP/FN 구하기 ------------------------------------------------------------------------------------
        # 여기서 true 값은 1차 라벨링값 predict 는 2차 라벨링값
        
        df_p = pd.DataFrame(pred_y, columns=['anomaly'])
        df_t = pd.DataFrame(error_df['True_class'].tolist(), columns=['anomaly'])
        
        anomaly_list_p = df_p[df_p['anomaly']==1].index
        anomaly_list_T = df_t[df_t['anomaly']==1].index
        anomaly_list_p = (anomaly_list_p +2).to_list()
        anomaly_list_T = (anomaly_list_T +2).to_list()

        TN = list(set(anomaly_list_T) & set(anomaly_list_p)) 
        FP = list(set(anomaly_list_p) - set(anomaly_list_T))
        FN = list(set(anomaly_list_T) - set(anomaly_list_p))
        
                          
        # anomaly index 만 리스트로 만들어서 dictionary 에 value 로 저장. ------------------------------------------------------------------------------------------
        isolationforest_parameter = j
        str_isolationforest_parameter = str(isolationforest_parameter)[2:]
        if(len(str_isolationforest_parameter) != 5  ):
            for i in range(5 - len(str_isolationforest_parameter)):
                str_isolationforest_parameter=str_isolationforest_parameter + '0'
            
        
        
        Save_dict_name = str(k)[7:20]
        content[Save_dict_name +'_p_'+ str(str_isolationforest_parameter)] = TN+FP+FN
        
        
        with open('anomaly_index.pickle','wb') as fw:
            pickle.dump(content, fw)
            
        file = open("anomaly_index.pickle",'rb')
        content = pickle.load(file)
        content.keys()

 

- kaggle luminol https://www.kaggle.com/caesarlupum/anomaly-detection-time-series-linkedin-luminol

- 위랑 똑같은데 알고리즘만 다름 https://www.kaggle.com/caesarlupum/anomaly-detection-time-series-changefinder#Glipse-Data

- 위에두개 작성한 사람이 cpd 알고리즘만 모아둔거 https://www.kaggle.com/general/128356

- pilly  - 

- rupture https://github.com/deepcharles/ruptures

ㄴ 이건 이상치 value 를 잡아줌 

- jenkspy  https://pypi.org/project/jenkspy/

ㄴ이건 이상치 key 를 잡아줌

 

'<Activity> > 21,22 컴퓨터 프로그래밍 강의조교' 카테고리의 다른 글

Python Turtle 정리  (0) 2022.04.11
파이썬 변수 이해하기  (0) 2021.03.19

'<개념> > 기타' 카테고리의 다른 글

푸리에 변환 초간단 정리  (0) 2022.01.30
SHIFT 개념 이해하기 예제 with SIN/COS/TAN  (0) 2021.12.30
RestfulAPI 개념정리  (0) 2021.08.14
AJAX,JSON 개념메모  (0) 2021.08.14
도커 초간단 개념정리  (0) 2021.05.09
  • 추세 (Trend) : 증가하는지 감소하는지
  • 계절성 (Seasonality) : 일정한 빈도로 주기적으로 반복되는 패턴( 𝑚 )
  • 잔차(Residual) : 데이터 - 추세(trend) - 계절성(seasonal)

그렇다면 잔차가 불규칙적인 값으로 seaonal 한 값(계절성) 이 유의미한 값이 되기위해서는 잔차(residual)이 다음과 같이 2가지 조건을 모두 만족해야합니다.

 

 

  1. 잔차는 (1) 정규분포이고 ,평균0과 일정한 분산을 가져야함

2. 잔차에 (1) 특정한 흐름이 있으면 안됨, 규칙성이 보이면안됨

 

위에 서술한 잔차의 2가지 조건을 만족하기위해서 총 4가지 방법으로 잔차진단을 수행합니다

잔차진단 ! (4가지)

 

 

pdf

T_잔차진단(백색잡음)_내용_정리.pdf
0.73MB

 

HTML

Export-c87bd7a2-b880-4893-b8fc-f28f28954473.zip
0.52MB

- 이건 300ms 마다 모든 항목 저장

nvidia-smi -lms 300 -f ./Data.csv --format=csv --query-gpu=timestamp,driver_version,count,name,serial,uuid,pci.bus_id,pci.domain,pci.bus,pci.device,pci.device_id,pci.sub_device_id,pcie.link.gen.current,pcie.link.gen.max,pcie.link.width.current,pcie.link.width.max,index,display_mode,display_active,persistence_mode,accounting.mode,accounting.buffer_size,driver_model.current,driver_model.pending,vbios_version,inforom.img,inforom.oem,inforom.ecc,inforom.pwr,gom.current,gom.pending,fan.speed,pstate,clocks_throttle_reasons.supported,clocks_throttle_reasons.active,clocks_throttle_reasons.gpu_idle,clocks_throttle_reasons.applications_clocks_setting,clocks_throttle_reasons.sw_power_cap,clocks_throttle_reasons.hw_slowdown,memory.total,memory.used,memory.free,compute_mode,utilization.gpu,utilization.memory,ecc.mode.current,ecc.mode.pending,ecc.errors.corrected.volatile.device_memory,ecc.errors.corrected.volatile.register_file,ecc.errors.corrected.volatile.l1_cache,ecc.errors.corrected.volatile.l2_cache,ecc.errors.corrected.volatile.texture_memory,ecc.errors.corrected.volatile.total,ecc.errors.corrected.aggregate.device_memory,ecc.errors.corrected.aggregate.register_file,ecc.errors.corrected.aggregate.l1_cache,ecc.errors.corrected.aggregate.l2_cache,ecc.errors.corrected.aggregate.texture_memory,ecc.errors.corrected.aggregate.total,ecc.errors.uncorrected.volatile.device_memory,ecc.errors.uncorrected.volatile.register_file,ecc.errors.uncorrected.volatile.l1_cache,ecc.errors.uncorrected.volatile.l2_cache,ecc.errors.uncorrected.volatile.texture_memory,ecc.errors.uncorrected.volatile.total,ecc.errors.uncorrected.aggregate.device_memory,ecc.errors.uncorrected.aggregate.register_file,ecc.errors.uncorrected.aggregate.l1_cache,ecc.errors.uncorrected.aggregate.l2_cache,ecc.errors.uncorrected.aggregate.texture_memory,ecc.errors.uncorrected.aggregate.total,retired_pages.single_bit_ecc.count,retired_pages.double_bit.count,retired_pages.pending,temperature.gpu,power.management,power.draw,power.limit,power.default_limit,power.min_limit,power.max_limit,clocks.current.graphics,clocks.current.sm,clocks.current.memory,clocks.applications.graphics,clocks.applications.memory,clocks.default_applications.graphics,clocks.default_applications.memory,clocks.max.graphics,clocks.max.sm,clocks.max.memory
더보기

nvidia-smi -lms 300 -f ./Data.csv --format=csv --query-gpu=timestamp,driver_version,count,name,serial,uuid,pci.bus_id,pci.domain,pci.bus,pci.device,pci.device_id,pci.sub_device_id,pcie.link.gen.current,pcie.link.gen.max,pcie.link.width.current,pcie.link.width.max,index,display_mode,display_active,persistence_mode,accounting.mode,accounting.buffer_size,driver_model.current,driver_model.pending,vbios_version,inforom.img,inforom.oem,inforom.ecc,inforom.pwr,gom.current,gom.pending,fan.speed,pstate,clocks_throttle_reasons.supported,clocks_throttle_reasons.active,clocks_throttle_reasons.gpu_idle,clocks_throttle_reasons.applications_clocks_setting,clocks_throttle_reasons.sw_power_cap,clocks_throttle_reasons.hw_slowdown,memory.total,memory.used,memory.free,compute_mode,utilization.gpu,utilization.memory,ecc.mode.current,ecc.mode.pending,ecc.errors.corrected.volatile.device_memory,ecc.errors.corrected.volatile.register_file,ecc.errors.corrected.volatile.l1_cache,ecc.errors.corrected.volatile.l2_cache,ecc.errors.corrected.volatile.texture_memory,ecc.errors.corrected.volatile.total,ecc.errors.corrected.aggregate.device_memory,ecc.errors.corrected.aggregate.register_file,ecc.errors.corrected.aggregate.l1_cache,ecc.errors.corrected.aggregate.l2_cache,ecc.errors.corrected.aggregate.texture_memory,ecc.errors.corrected.aggregate.total,ecc.errors.uncorrected.volatile.device_memory,ecc.errors.uncorrected.volatile.register_file,ecc.errors.uncorrected.volatile.l1_cache,ecc.errors.uncorrected.volatile.l2_cache,ecc.errors.uncorrected.volatile.texture_memory,ecc.errors.uncorrected.volatile.total,ecc.errors.uncorrected.aggregate.device_memory,ecc.errors.uncorrected.aggregate.register_file,ecc.errors.uncorrected.aggregate.l1_cache,ecc.errors.uncorrected.aggregate.l2_cache,ecc.errors.uncorrected.aggregate.texture_memory,ecc.errors.uncorrected.aggregate.total,retired_pages.single_bit_ecc.count,retired_pages.double_bit.count,retired_pages.pending,temperature.gpu,power.management,power.draw,power.limit,power.default_limit,power.min_limit,power.max_limit,clocks.current.graphics,clocks.current.sm,clocks.current.memory,clocks.applications.graphics,clocks.applications.memory,clocks.default_applications.graphics,clocks.default_applications.memory,clocks.max.graphics,clocks.max.sm,clocks.max.memory

 

 

- 이건 1초마다 모든항목 저장

nvidia-smi -l 1 -f ./Data.csv --format=csv --query-gpu=timestamp,driver_version,count,name,serial,uuid,pci.bus_id,pci.domain,pci.bus,pci.device,pci.device_id,pci.sub_device_id,pcie.link.gen.current,pcie.link.gen.max,pcie.link.width.current,pcie.link.width.max,index,display_mode,display_active,persistence_mode,accounting.mode,accounting.buffer_size,driver_model.current,driver_model.pending,vbios_version,inforom.img,inforom.oem,inforom.ecc,inforom.pwr,gom.current,gom.pending,fan.speed,pstate,clocks_throttle_reasons.supported,clocks_throttle_reasons.active,clocks_throttle_reasons.gpu_idle,clocks_throttle_reasons.applications_clocks_setting,clocks_throttle_reasons.sw_power_cap,clocks_throttle_reasons.hw_slowdown,memory.total,memory.used,memory.free,compute_mode,utilization.gpu,utilization.memory,ecc.mode.current,ecc.mode.pending,ecc.errors.corrected.volatile.device_memory,ecc.errors.corrected.volatile.register_file,ecc.errors.corrected.volatile.l1_cache,ecc.errors.corrected.volatile.l2_cache,ecc.errors.corrected.volatile.texture_memory,ecc.errors.corrected.volatile.total,ecc.errors.corrected.aggregate.device_memory,ecc.errors.corrected.aggregate.register_file,ecc.errors.corrected.aggregate.l1_cache,ecc.errors.corrected.aggregate.l2_cache,ecc.errors.corrected.aggregate.texture_memory,ecc.errors.corrected.aggregate.total,ecc.errors.uncorrected.volatile.device_memory,ecc.errors.uncorrected.volatile.register_file,ecc.errors.uncorrected.volatile.l1_cache,ecc.errors.uncorrected.volatile.l2_cache,ecc.errors.uncorrected.volatile.texture_memory,ecc.errors.uncorrected.volatile.total,ecc.errors.uncorrected.aggregate.device_memory,ecc.errors.uncorrected.aggregate.register_file,ecc.errors.uncorrected.aggregate.l1_cache,ecc.errors.uncorrected.aggregate.l2_cache,ecc.errors.uncorrected.aggregate.texture_memory,ecc.errors.uncorrected.aggregate.total,retired_pages.single_bit_ecc.count,retired_pages.double_bit.count,retired_pages.pending,temperature.gpu,power.management,power.draw,power.limit,power.default_limit,power.min_limit,power.max_limit,clocks.current.graphics,clocks.current.sm,clocks.current.memory,clocks.applications.graphics,clocks.applications.memory,clocks.default_applications.graphics,clocks.default_applications.memory,clocks.max.graphics,clocks.max.sm,clocks.max.memory
더보기

nvidia-smi -l 1 -f ./Data.csv --format=csv --query-gpu=timestamp,driver_version,count,name,serial,uuid,pci.bus_id,pci.domain,pci.bus,pci.device,pci.device_id,pci.sub_device_id,pcie.link.gen.current,pcie.link.gen.max,pcie.link.width.current,pcie.link.width.max,index,display_mode,display_active,persistence_mode,accounting.mode,accounting.buffer_size,driver_model.current,driver_model.pending,vbios_version,inforom.img,inforom.oem,inforom.ecc,inforom.pwr,gom.current,gom.pending,fan.speed,pstate,clocks_throttle_reasons.supported,clocks_throttle_reasons.active,clocks_throttle_reasons.gpu_idle,clocks_throttle_reasons.applications_clocks_setting,clocks_throttle_reasons.sw_power_cap,clocks_throttle_reasons.hw_slowdown,memory.total,memory.used,memory.free,compute_mode,utilization.gpu,utilization.memory,ecc.mode.current,ecc.mode.pending,ecc.errors.corrected.volatile.device_memory,ecc.errors.corrected.volatile.register_file,ecc.errors.corrected.volatile.l1_cache,ecc.errors.corrected.volatile.l2_cache,ecc.errors.corrected.volatile.texture_memory,ecc.errors.corrected.volatile.total,ecc.errors.corrected.aggregate.device_memory,ecc.errors.corrected.aggregate.register_file,ecc.errors.corrected.aggregate.l1_cache,ecc.errors.corrected.aggregate.l2_cache,ecc.errors.corrected.aggregate.texture_memory,ecc.errors.corrected.aggregate.total,ecc.errors.uncorrected.volatile.device_memory,ecc.errors.uncorrected.volatile.register_file,ecc.errors.uncorrected.volatile.l1_cache,ecc.errors.uncorrected.volatile.l2_cache,ecc.errors.uncorrected.volatile.texture_memory,ecc.errors.uncorrected.volatile.total,ecc.errors.uncorrected.aggregate.device_memory,ecc.errors.uncorrected.aggregate.register_file,ecc.errors.uncorrected.aggregate.l1_cache,ecc.errors.uncorrected.aggregate.l2_cache,ecc.errors.uncorrected.aggregate.texture_memory,ecc.errors.uncorrected.aggregate.total,retired_pages.single_bit_ecc.count,retired_pages.double_bit.count,retired_pages.pending,temperature.gpu,power.management,power.draw,power.limit,power.default_limit,power.min_limit,power.max_limit,clocks.current.graphics,clocks.current.sm,clocks.current.memory,clocks.applications.graphics,clocks.applications.memory,clocks.default_applications.graphics,clocks.default_applications.memory,clocks.max.graphics,clocks.max.sm,clocks.max.memory

<맥북기준> 현재 위치에 인스턴스내 모든 파일 저장

scp -i /Users/yyyooo/desktop/aws_pem/ys.pem -r ubuntu@18.206.202.171:/home/ubuntu/Hardware-Data/ .

- 18.206~ 이건 본인 인스턴스  퍼블릭 IPv4 주소 로 바꿔주면 되고, ec2 일경우 ubuntu 말고 아마 ec user? 로 바꿔주면 될것

- ys.pem 이건 본인 pem 키 위치 바꿔서 넣어주면된다. (yyyoo는 내 노트북내 내이름)

- /home/ubuntu/Hardware-Data/ .  => 이거는 왼쪽에 옮겨줄 ec2 내 파일위치 / 오른쪽 . 이건 내 현재 위치 말함

 

<윈도우 기준>

scp -i C:/Users/Owner/Desktop/ys2.pem -r ubuntu@54.226.138.113:/home/ubuntu/Hardware-Data/ .

 

 

<ID, 주소, 버전 관련>

 

이름 Description
Driver Version NVIDIA display driver 에 설치된 버전
CUDA Version  추천 버전, 현재 사용되고 있는 버전이 아님
Serial Number 보드의 물리적인 일련번호를 의미하고 고유한값
GPU UUID      Globally unique 하며, 변경불가하다. 보드의 물리적인 라벨과 일치하지 않는다 (uuid는 암호화 알고리즘을 사용해서 만들고 시리얼 타입보다 훨씬 복잡)
Board ID  드라이버가 할당한 고유한 보드 ID (예: 둘이상 gpu 가 동일 보드 id를 가지고 바로위에 멀티지피유=true 라면, 동일 보드위에 gpu들이 있다는걸 의미한다)
GPU Part Number   부품번호
Inforom Version (Image Version,OEM Object,ECC Object) gpu 비휘발성 저장장치 버전(gpu 구성,상태 데이터에 대한 소규모 영구 저장소)
Power Management Object Version for the 전원관리 데이터
Bus PCI bus number (아래 사진첨부) (pci segment = Pci bus = pci)
Device PCI device number
Domain PCI domain number(각 도메인은 256개 PCI 버스를 가질수 있음)
Device Id PCI vendor device id
Bus Id    PCI bus id (멀티 지피유의 경우 여러개가 뜸)
Sub System Id PCI Sub System i
PCIe Generation (max,current) PCLe 3.0 4.0 이런식으로 나뉘는데 4.0이 3.0보다 2배 빠르다.
Link Width((max,current) (×1, ×2, ×4, ×8, ×12, ×16 and ×32)링크는 두 PCI Express 포트 사이의 지점간 통신 채널
Process ID ,Type, Name,Used GPU Memory 프로세스 아이디, 타입은 CPU 이면 C , GPU 이면 G, CPU+GPU 이면 C+G, name python, used gpu memory 는 context 에 의해서 사용된 메모리양
VBIOS Version           VBIOS (컴퓨터를 부팅시에 가장먼저 시작되고,GPU 를 초기화) 버전

 

<리눅스에서만 사용하는 or 특정 인스턴스에서만 적용가능>

 

이름 Descriptoin
MIG Mode 7개 개별 인스턴스로 분할해서 사용가능함, A100( p4 instance )에서만 가능, 리눅스 에서 동작)
Driver Model 윈도우 0, linux x
Clocks Throttle Reasons (Idle,Applications Clocks Setting,SW Power Cap) 클록 빈도를 줄이는 요인에 대한 정보를 검색, Kepler 제품군에서 지원되는 Tesla 장치에서만 가능하다고한다 (전력 상한선 제한)
Power Limit         소프트웨어 전력 제한(와트). nvidia-smi와 같은 소프트웨어로 설정합니다. 전원 관리가 지원되는 경우에만 사용할 수 있습니다. Inforom PWR 개체 버전 3.0 이상 또는 Kepler 장치가 필요/ 특별히 지정한값이 없으면 디폴트 파워 리밋과 동일함.
GPU Operation Mode p3,g3 인스턴스에서만 지원가능 (GOM 을 사용하면 gpu 기능을 비활성화해서 전력 사용량을 줄이고 GPU 처리량을 최적화할수 있다고함)
Persistence Mode GPU 에 대해서 지속성모드가 활성화되어있는지 여부를 나타내는 FLAG. Enabled 되어있으면 Cuda 프로그램같은 종속앱실행과 관련된 드라이버 로드 대기시간이 최소화, (리눅스에서만 지원)
Minor Number              다중 GPU 시스템에서 여러 작업을 병렬로 시작할때 사용 (dev/nvidia [minor number] 형식을 가지게함, only linux)

 

<전력, 온도관련>

 

이름 Description
Applications Clocks Setting GPU 클럭은 애플리케이션 클럭 설정에 의해 제한. 예를 들어 nvidia-smi --applications-clocks=를 사용하여 변경가능 (gpu clock 제한유무)
SW Power Cap        SW Power Scaling 알고리즘은 GPU가 너무 많은 전력을 소비하기 때문에 요청된 클럭 아래로 클럭을 줄이고 있습니다. 예를 들어 SW 전력 상한선은 nvidia-smi --power-limit=로 변경가능
FB Memory Usage (total,used,free) frame buffer memory : 레스터주사방식(화면의 다수를 화소로 분할, 화면의 위에서부터 수평주사선을 옆으로 끌듯이 한줄씩 아래로 내려가면서 주사하여 화면을 형성하는 주사방식) 에서 화면에 나타날 영상정보를 일시적으로 저장하는 기억장치
BAR1 Memory Usage (total,used,free) BAR1은 FB(장치 메모리)를 매핑하는 데 사용되어 CPU 또는 타사 장치(PCIe 버스의 피어 투 피어)에서 직접 액세스할 수 있습니다.VRAM ? GPU RAM, 해상도가 커지면 한화면에 출력해야할 오브젝트들이 많아지기 떄문에 VRAM 의존도가 기하급수적으로 커진다.
Utilization (Gpu,Memory,Encoder,Decoder) 활용률은 각 GPU가 시간이 지남(1/6초~1초)에 따라 얼마나 사용하는지 보고하며 시스템에서 응용 프로그램이 GPU를 얼마나 사용하고 있는지 확인하는 데 사용할 수 있습니다.
ECC Errors NVIDIA GPU는 다양한 유형의 ECC 오류에 대한 오류 수를 제공
Temperature(GPU Current Temp,GPU Shutdown Temp,GPU Slowdown Temp,GPU Max Operating Temp,Memory Current Temp,Memory Max Operating Temp) 보드에 있는 온도 센서의 판독값.
Power Readings (Power Management,Power Draw,Default Power Limit,Enforced Power Limit,Min Power Limit,Max Power Limit) 전체 보드에 대해 측정된 전력 소비량(와트) (power Limit 설정은 Kepler 장치만 가능)
Clocks (Graphics,SM,Memory,Video) GPU의 일부가 실행되는 현재 주파수. 모든 판독값은 MHz 단위
Applications Clocks (Graphics,Memory,Default Applications Clocks,Max Clocks) 애플리케이션이 실행될 기본 빈도.(코어클럭 : 그래픽 프로세서의 코어 속도를 나타냄, 메모리클럭 : GPU의 VRAM 주파수 , VRAM 은 GPU에서 사용하는 램. DRAM 과 달리 VRAM 은 GPU가 렌더링해야하는 자산에 대한 메모리를 유지하는데 사용됨)

<사용자 설정가능>

 

이름 Description
Applications Clocks Setting [전력,온도 관련 중복] GPU 클럭은 애플리케이션 클럭 설정에 의해 제한. 예를 들어 nvidia-smi --applications-clocks=를 사용하여 변경가능
SW Power Cap      SW Power Scaling 알고리즘은 GPU가 너무 많은 전력을 소비하기 때문에 요청된 클럭 아래로 클럭을 줄인다. 예를 들어 SW 전력 상한선은 nvidia-smi --power-limit=로 변경가능
Max Customer Boost Clocks 사용자가 지정한 최대 boost 클럭속도
Applications Clocks (Graphics,Memory) 애플리케이션이 실행될 기본 빈도.(사용자지정 그래픽 주파수,사용자지정 메모리 주파수)
Clock Policy 자동클럭 변경에 대한 사용자지정 설정
MIG Mode 7개 개별 인스턴스로 분할해서 사용가능함. nvidia-smi -mig 1 이 명령어로 mig mode를 disable,enable 바꿔줄수 있다./ $ sudo nvidia-smi mig -cgi 9,3g.20gb 이런식으로 인스턴스를 나눠줄수 있음.

 

<그외 중요하다고 생각한 것들>

 

이름 Description
Attached GPUs 시스템에 있는 NVIDIA GPU 개수
Product Name        Ex: Tesla T4 (GPU product name)
MultiGPU Board      멀티 지피유 보드인지 아닌지
Tx Throughput (Transmit Data) 바로전 20ms 동안 PCIe 버스를 통한 GPU 중심 전송 처리량(MB/s). Maxwell 아키텍처 이상에서만 지원
Rx Throughpu (Receive Data의) GPU 중심은 바로전 20ms 동안 MB/s 단위의 PCIe 버스를 통한 수신 처리량. Maxwell 아키텍처 이상에서만 지원
Performance State GPU 현재성능상태로 P0-P12까지 있꼬, P0이 최대성능

 

 

PDF

T_nvidia-smi_-q_비슷한_유형별로_모아보기.pdf
0.39MB

 

HTML

Export-63ff0091-088a-4e31-acdb-5dcb09293db3.zip
0.13MB

#!/bin/bash = #!/bin/sh

ㄴ 스크립트파일 bash쉘로 실행. 기본적으로 bash 쉘로 되어있어서 굳이 안써도 상관은없는데 오류방지를 위해 쓰는것이 좋다.

 

EC2 CLI

run-instances
[--block-device-mappings <value>]
[--image-id <value>]
[--instance-type <value>]
[--ipv6-address-count <value>]
[--ipv6-addresses <value>]
[--kernel-id <value>]
[--key-name <value>]
[--monitoring <value>]
[--placement <value>]
[--ramdisk-id <value>]
[--security-group-ids <value>]
[--security-groups <value>]
[--subnet-id <value>]
[--user-data <value>]
[--additional-info <value>]
[--client-token <value>]
[--disable-api-termination | --enable-api-termination]
[--dry-run | --no-dry-run]
[--ebs-optimized | --no-ebs-optimized]
[--iam-instance-profile <value>]
[--instance-initiated-shutdown-behavior <value>]
[--network-interfaces <value>]
[--private-ip-address <value>]
[--elastic-gpu-specification <value>]
[--elastic-inference-accelerators <value>]
[--tag-specifications <value>]
[--launch-template <value>]
[--instance-market-options <value>]
[--credit-specification <value>]
[--cpu-options <value>]
[--capacity-reservation-specification <value>]
[--hibernation-options <value>]
[--license-specifications <value>]
[--metadata-options <value>]
[--enclave-options <value>]
[--count <value>]
[--secondary-private-ip-addresses <value>]
[--secondary-private-ip-address-count <value>]
[--associate-public-ip-address | --no-associate-public-ip-address]
[--cli-input-json <value>]
[--generate-cli-skeleton <value>]

describe-instances
[--filters <value>]
[--instance-ids <value>]
[--dry-run | --no-dry-run]
[--cli-input-json <value>]
[--starting-token <value>]
[--page-size <value>]
[--max-items <value>]
[--generate-cli-skeleton <value>]
LAUNCH_INFO=$(aws ec2 run-instances --image-id $IMAGE_ID --count 1 --instance-type $INSTANCE_TYPE \
--key-name $AWS_KEY --subnet-id $SUBNET_ID --security-group-ids $SG_ID)

 

[--count <value>]

시작할 인스턴스 수.(기본값은 1). 범위가 min:max 형식으로 제공되면 첫 번째 숫자는 시작할 최소 인스턴스 수로 해석되고 두 번째 숫자는 시작할 최대 인스턴스 수로 해석함.

[--image-id <value>]

AMI의 ID. AMI ID는 인스턴스를 시작하는 데 필요하며 시작할떄 지정해줘야함.

[--instance-type <value>]

인스턴스 타입 (ex:g4dn.xlarge)

[--key-name <value>]

키 쌍의 이름. (CreateKeyPair 또는 ImportKeyPair 를 사용하여 키 페어를 생성할 수 있다.)

[--subnet-id <value>]

[EC2-VPC] 인스턴스를 시작할 서브넷의 ID. 네트워크 인터페이스를 지정하는 경우 서브넷을 네트워크 인터페이스의 일부로 지정해야 함.

[--security-group-ids <value>]

보안 그룹의 ID. (CreateSecurityGroup을 사용하여 보안 그룹을 만들 수 있다.) 네트워크 인터페이스를 지정하는 경우 보안 그룹을 네트워크 인터페이스의 일부로 지정해야 한다.

**** echo**

확인용 https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-usage-returncodes.html

[--instance-ids <value>]

The instance IDs. (Default: Describes all your instances.)

 

 

JQ

  • jq로 json 처리하기

ㄴ -query로 수행할 수 없는 고급 필터링의 경우 명령줄 JSON 프로세서인 jq를 고려할 수 있다.

더보기
더보기
더보기

INSTANCE_ID=$(echo $LAUNCH_INFO | jq -r '. | .Instances[0].InstanceId')

$ cat sample.json
{"data":{"name":"myname","values": [{"id": "id0","url": "url0"},{"id": "id1","url": "url1"},{"id": "id2","url": "url2"}]}}
$ cat sample.json | jq .
{
  "data": {
    "name": "myname",
    "values": [
      {
        "id": "id0",
        "url": "url0"
      },
      {
        "id": "id1",
        "url": "url1"
      },
      {
        "id": "id2",
        "url": "url2"
      }
    ]
  }
}

. (점하나)

입력그대로 출력함

.foo (점다음에 key값)

점다음에 키값의 value를 출력한다.

.foo = .["foo"] = ."foo"

 

.[] (점뒤에 괄호)

 

결과 9 8

|(파이프)

두개 필터를 결합함.

ex) .a | . | .b = .a.b

.a.b.c = .a | .b | .c.

-raw-output / -r (ex: jq -r)

필터의 결과가 문자열이면 따옴표가 있는 JSON 문자열로 형식이 지정되지 않고 표준 출력에 직접 기록됨. non-JSON-based systems과 통신할때 사용.

사용예제 : https://gist.github.com/hummus/8592113

여러줄일때는 맨뒤에 \ 붙이고 이어서 다음줄에 줄줄이 쓰면됨

입력그대로 출력함

 

 

 

EC2 describe~

  • EC2 특징출력하기

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-usage-filter.html

$ aws ec2 describe-volumes

  • EC2 인스턴스들 나열하고 정보확인하기

https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cli-services-ec2-instances.html

 

 

aws ec2 describe-instances --instance-ids i-12abc34 --query 'Reservations[].Instances[].PublicDnsName'

ㄴ i-12abc34 라는 인스턴스아이디를 가진 인스턴스의 PublicDnsName

 

 

 

 

 

  • Driver Version : 사용하고있는 GPU-Dirver 버전
  • CUDA Version : 사용하고 있는 쿠다 버전이 아니다!! 사용하고 있는 드라이버의 추천 쿠다버전이다.

실제 쿠다버전확인 : nvcc—version or nvcc-V

  • GPU/FAN : 0-7 까지는 GPU_number 이고 N/A 표기된곳은 FAN이 장착되어있는 GPU 사용시 사용퍼센테이지로 표시가된다.→ testla 계열은 팬이 없다고한다. Geforce,rtx등에 fan이 있다. 위는 p2 인스턴스, tesla k80 이기 때문에 팬이 존재하지않는다.
  • Persistence-M : on 인 상태는 파워제한을 걸수 있다. 이로써 gpu 사용시 지연되는 시간을 아낄수있다.
  • Temp : 일정온도가 지나면 성능저하가 발생한다고한다.
  • Perf : performance mode로 p0-p12까지 있다고한다. 숫자가 작을수록 많은 high-performance 상태이다.
  • Pwr:Usage/cap : GPU 현재 사용량과 / 최대용량
  • bus-id : mainboard 슬롯에 bus-id 라는것이 있는데 위의 결과를 토대로 보면bus-id 0000:00:iE.0 을 확인후 mainboard 에 해당하는 위치의 gpu를 찾을수 있다는것을 의미한다.
  • disp.a : 리눅스 설치시 server와 데스크탑 버전이 있다. 데스크탑버전으로 설치되면 화면출력을 gpu-card로 하는것이 좋다고한다. 보통은 disp.a.off 상태가 보통이지만 on 되어있다는것은 GPU_card에 출력이 되고있다는 의미라고한다.
  • Memroy-usage : GPU 별로 gpu-memory 크기가 다른데 현재 10903mib를 사용하고 있다는 의미, 11441mib 가 gpu total memory
  • uncorr.ecc : GPU error count 모드를 on/off
  • Compute M 현재 사용중인 compute mode 가 나온다. 0. Default 모드이다. 그외에 1.Exclusive_thread 2. Prohibited 3. Exclusive_process 모드가 있다.
  • Process : GPU 0-7 PID 등 현재 사용중인 내용들이 출력된다.

 

GPU 메모리가 부족하다는뜻이다. 해결책으로는

1. 데이터셋 크기 줄이기 

2. 배치사이즈 줄이기

3. 메모리가 큰 인스턴스 사용하기 ( 단순 메모리만 늘린다고 큰 인스턴스를 사용했다가는 멀티 지피유를 사용하게되고 가격폭탄을 맞을수 있다.. 조심조심...)

https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8924184 (논문pdf 링크)

노션 참조 

참조 :

http://www.nextobe.com/2020/05/14/딥러닝을위한-멀티-gpu-시스템-구축-및-사용-방법/

https://www.udna.kr/post/gpu-클러스터-관리의-어려움을-한-방에-해결하는-gpu-on-demand

https://www.samsungsds.com/kr/insights/TechToolkit_2021_GPU.html

 

 

ABSTRACT

클라우드의 다양한 구성 옵션에서 딥 러닝 모델을 훈련하기 위한 런타임 및 비용을 추정하는 클라우드 서비스인 AI 게이지를 제공한다.

INTRODUCTION

  • GPU 종류에 따라 10배까지도 실행속도 차이가 남
  • 여러가지 선택지들은 많지만 어떤 하드웨어를 사용할것인지는 아직도 사용자의 몫 (뭐가 좋을지 선택은 사용자가)
  • 런타임은 비용과 비례함
  1. 클라우드에서 기계 학습 작업의 런타임을 추정할것임 (온라인,오프라인 모두 성능 추정치를 제공하고, 비용예산및 성능 목표에 따라 선택할수있는 바람직한 옵션을 제공할것이라고함)
  1. 클라우드에서 딥 러닝 훈련 작업의 런타임 예측을 위한 비선형 회귀 모델을 개발 - 오프라인
  1. 학습 로그를 사용하여 클라우드에서 진행 중인 작업의 남은 런타임 추정을 위한 기술을 개발. 서비스는 작업을 실행하는 기본 DL 프레임워크와 독립적인 일반화된 형식으로 로그를 사용 - 온라인

II. CHALLENGES & USE CASES

A. Challenges in Building a Runtime Estimation Service

  1. 계속 DL 요소들과 GPU 갯수들 등등 많은 요소들에 의해 런타임 예측이 아주 복잡하다는걸 계속 반복해서 말하고 있다.
  1. 여러가지 프레임워크에도 적용되는 유연성을 제공할것이라고 한다.

B. AI Gauge Use Cases

  • 현재 딥러닝 실험을 위한 프레임워크 제공 경쟁이 치열하다 (= 한마디로 사용자가 지정가능한 옵션들이 매우 다양하다는 의미)
  • AI 게이지 서비스는 이런 서비스속에서 사용자가 어떤 GPU 유형을 선택해야할지,몇개를 선택할지(멀티지피유), 얼마나 오래 실행할것인지 , 얼마나 가성비좋은 선택인지등등 사용자의 질문에 답하는데 도움을 줄것
  • 한마디로 다양한 GPU 구성에 따른 작업 런타임 및 총 비용의 추정치를 제공할것

III. AI GAUGE SERVICE DESIGN

  • AI gauge 는 1)온라인 견적서비스 2)오프라인 견적서비스 이렇게 두가지를 제공

** 오프라인 : 미리 트레이닝해놓고 적용.

** 온라인 : 온라인 학습에서는 데이터를 순차적으로 미니배치별로 시스템을 훈련.온라인 학습은 연속적으로 데이터를 받고 빠른 변화에 스스로 적응해야 하는 시스템에 적합하다.

A. AI Gauge service overview

 

  • AI gauge 아키텍쳐에 대해 설명하고 있다.
  • API 를 사용하여 사용자와 서비스가 상호작용할수 있게 해준다
  • JOB Monitoring Service ⇒ 실행중인 잡의 진행상황을 모니터링하기 위해 개발.(It records the job progress as a time series with epoch/iteration numbers.)
  • online estimation service ⇒ retrieve the latest job progress from the database directly
  • 예측 결과등 시각화를 제공하기 위해 Grafana 대시보드를 사용해서 배포한다고 한다.
  • ** Grafana (개방형 분석및 모니터링 플랫폼)

    Grafana란, 시계열 매트릭 데이터를 시각화 하는데 가장 최적화된 대시보드를 제공해주는 오픈소스 툴킷이다. 다양한 DB를 연결하여 DB의 데이터를 가져와 시각화 할 수 있으며, 그래프를 그리는 방법도 간단히 마우스 클릭으로 완료할 수 있다.

    Grafana는 시계열 매트릭 데이터 수집에 강한 모습을 보이는 만큼, 활용하는 부분도 서버 리소스의 매트릭 정보나 로그 같은 데이터를 시각화는 데 많이 사용한다.

    시각화한 그래프에서 특정 수치 이상으로 값이 치솟을 때(예를 들어 CPU 사용량 80% 이상) 알림을 전달받을 수 있는 기능도 제공한다. 이러한 기능은 인프라 운영 관점에서 굉장히 중요한 기능이라고 할 수 있다.

    예시로 볼수있는 링크 : https://play.grafana.org/d/000000012/grafana-play-home?orgId=1

 

B. AI Gauge service request flows

  • AI Gauge 는 3가지 기능을 제공한다
    1. 실행중인 작업을 모니터링 ( Grafana 가 실시간 모니터링에 적합한 플랫폼인것같다 ex:kibana)ㄴ 작업 모니터링 서비스
    1. 실행중인 작업의 남은 런타임 및 비용추정ㄴ 온라인 견적서비스
    1. 작업의 총 실행시간과 비용을 추정ㄴ 오프라인 견적 서비스
    이 3가지는 완전히 본리되어있고 서로 상호호환하지않는다.

IV. ONLINE ESTIMATION (제공하는 두번째 서비스)

  • 온라인 예측 (2번째 서비스) 는 작업이 시작되고 나서야 사용가능하며, 남은 런타임을 에측한다.
  • 사용자는 AI 게이지를 사용하려면 Epoch/iteration 시간당 및 현재 완료된 Epoch/iteration 횟수에 관한 정보를 알아야한다.
  • 시계열 데이터를 기반으로 하기때문에 데이터의 시간적 속성을 연구해야한다.(= 시계열이 정상적이여야한다)
  • 그림4에서 1, 2, 4 GPU가 있는 작업은 단일 노드인 반면, 8 GPU 작업은 2노드에 분산된 작업이다.
  • 그림4에서 단일노드, 분산작업 모두다 iteration 별로 아주작은 변동은 존재하지만, 특별한 경향성이나 계절성같은것은 보이지않는다.
  • 그림4를 보면, Caffe jobs의 시간별 시계열 데이터를 보여주는데, 8개 gpu 작업에서 배치사이즈가 다른것보다 거의 2배인걸 확인할수있다.
  • ADF 테스트에서 실패한 작업들을 더 살펴보았다고한다, → 모든 작업의 총 에포크가 100개미만이고 테스트할 데이터 포인트가 너무 작아서 테스트가 실패했다는 이유를 발견함
  • 그다음으로 각 잡 타입에 따라 (모델과, gpu 를 달리해서) 잡 실행시간을 비교하기위해 coV를 계산.
  • ** IBM WML

    IBM 에서 제공하는 클라우드 서비스인가보다

    https://ibm-wml-api-pyclient.mybluemix.net/

    IBM 왓슨 기계 학습 서비스와 함께 작업 할 수 있습니다. 모델을 훈련, 저장 및 배포하고 API를 사용하여 점수를 매기고 마지막으로 애플리케이션 개발과 통합할 수 있습니다. ibm-watson-machine-learning라이브러리는 데이터 버전 3.5 이상에서 (나중에 IBM 클라우드라고 함) 서비스로 데이터를위한 IBM 클라우드 Pak® (2020 년 9 월 1 일 이후에 생성) V2 인스턴스 계획뿐만 아니라 IBM 클라우드 Pak® 작업 할 수 있습니다. 이전 버전의 IBM Cloud Pak® for Data의 경우 링크에 제공된 라이브러리의 베타 버전을 사용하십시오 .

  • ** ADF test ( Augmented Dicky-Fuller Test)
    • 시계열 데이터를 테스트하는 방법
    • 주로 시계열 데이터가 안정적인가? 여부를 확인하는데 이용되는 방법이다
    • 귀무가설 ( null hypothesis ) : 기각에 실패하면 시계열이 안정적이지 않음을 의미한다.
    • Alernative hypothesis 귀무가설이 기각되고 시계열이 안정적임을 의미한다.
    • 귀무가설을 기각하기 위해서는 p-value 가 0.05보다 낮게 나와야한다고 한다. 그 이상이면 시계열 데이터가 안정적이지않다는것을 의미한다.

V. OFFLINE ESTIMATION (제공하는 세번째 서비스)

 

  • 오프라인 견적 서비스는 클라우드에서 돌리기전에!!!! 실행해서 제공한다.
  • 이 제공된 추정치를가지고 사용자에게 가장 적합한 리소스구성을 제안한다. 즉 사용자가 잡관련 설명만 인풋으로 넣으면, 오프라인 견적 서비스는 아웃풋으로 비용 & 리소스 구성목록을 반환한다.
  • 피처로 플랫폼 하드웨어 특성뿐만 아니라, DL 클러스터와 관련된 피처들도 고려하기위해서 DL 클러스터의 작업로그를 분석했다.
  • 여기서 문제점 : 표1에 나오는 다양한 요소조합을 포함하는 공개 데이터를 찾을수 없었다. → 그래서 이것은 클러스터에서 실행되는 실제 사용자 작업에 대한 런타임 데이터로 보완이 되었다
  • 이것에 그치지않고 클러스터에서 더 많은 작업 추적이 수집될때, 예측모델을 점진적으로 조정하기 위해 오프라인 추정 구성요소는 확장가능한 설계를 가지고 있다. 재교육도 가능하다.
  • 기계 학습 모델에 사용되는 일반적인 성능 메트릭에는 평균 제곱 오류, 평균 절대 오류, 평균 제곱 로그 오류, 중간 절대 오류 및 R-제곱이 포함됩니다. 그러나 런타임 추정을 위한 예측 정확도는 초 단위의 절대 오차로 잘 설명되지 않습니다. 1분이라는 동일한 오류가 10시간 작업에는 작을 수 있지만 2분 작업에는 클 수 있습니다.
  • 현재 모델은 nonlinear regression and machine learning techniques like decision tree, random forest, and gradient boosting.
  • CART 알고리즘을 사용하여 결정트리를 구성함

 

VI. PERFORMANCE EVALUATION

A. Online Runtime Estimation

  • 그림6을 보면 4개의 장기 실행작업의 남은 실행시간을 살펴본다.ㄴ 예측한것과 실제 남은양이 거의같은걸 볼수있다.
  • 온라인 추정은 작업로그에서 읽은 반복시간에 이동평균을 사용하고 남은 런타임을 계산한다.
  • 그림7에서도 100K 반복에 대해 CIFAR10 데이터 세트[12]에서 실행된 Tensorflow ResNet 모델의 예상값과 실제값을 비교해서 보여준다.
  • 잔여 런타임을 구하기위해서 반복 런타임에 지수 가중이동평균을 적용해서 얻는다고한다 ( 10프로안짝의 오류로 싱글!!!!!!!!지피유!!!!!에 대한 우수한 에측을 제공한다고함

 

B. Offline Runtime Estimation

  • 이미지 분류를 위해 Pytorch 교육 작업을 사용하여 오프라인 런타임 추정을 평가합니다. 다양한 구성으로 옥스포드 꽃 데이터 세트에 대해 여러 이미지 분류기를 훈련하여 작업 추적을 수집했다.그리고나서 한 에포크당 평균시간을 측정
  • The configurations covered the feature space of network (Alexnet, ResNet18, ResNet50, VGG16); GPU-type (K80, P100, V100); number of learners (1,2,4); batch-size (16, 32, 64, 128, 256); and data-loading threads (0, 1, 2, 4, 8, 16, 32).
  • 여러가지 ML 모델개발 ( 5중교차검증사용, 521개의 데이터 포인트를 416개의 훈련 세트와 105개의 검증 세트로 무작위로 나눔)

 

  • y 가 예측한 에포크 레이턴시
  • I1, ..., I4는 One-Hot의 이진 변수
  • W는 작업자 수, B는 배치 크기, T는 스레드 수, F는 상대 네트워크 수
  • GPU 플롭의 경우 K80의 경우 1.87, P100의 경우 5.3, V100의 경우 7.8을 사용 (이는 K40에 대한 GPU 플롭의 비율)
  • 실험적으로 T와 F에 따라 런타임이 감소한다는 것을 관찰했고, 따라서 (2)에서 분모에 T와 F를 추가
  • 그림 8-a 는 선형 모델 2에 대한 테스트 데이터 세트에 대한 상대 오차(예: |y - y~|/y)의 CDF(누적 분포 함수)를 표시
  • (수정된) 선형 회귀 모델의 성능이 떨어지는 이유 중 하나는 종속 변수가 모델 매개변수의 기능에 대한 복잡한 비선형 종속성을 가질 수 있고 간단한 1차 비선형 항이 이를 포착할 수 없기 때문입니다. 예를 들어, 작업자 수 W는 그림 8b와 같이 Epoch 시간과 비선형 관계를 갖습니다. 이 비선형성을 포착하려면 일반 회귀 모델을 조사해야 합니다.

 

2) Nonlinear ML Models with One-Hot-Encoding:

  • 여기서는 런타임 추정을 위해 의사결정 트리, 랜덤 포레스트, 그래디언트 부스팅, 심층 신경망(DNN)의 네 가지 ML 모델을 제안!!!!!
  • 피처는 10개 사용 !!!! (OneHot-Encoding을 사용하여 3개의 숫자 변수와 7개의 이진 변수(네트워크 유형용 이진 변수 4개, GPU 유형용 이진 변수 3개)를 포함하여 10개의 독립 변수를 갖습니다)
  • 비선형 ML 모델 하이퍼파라미터 세트는 1. 트리최대깊이 2. 랜덤포레스트 부트스트랩사용여부 3. 그래디언트 부스팅 추정기수,학습률,최대특징수비율 4. DNN 레이어마다 노드개수
  • 표2 보면 바로확 이해갈것
  • 모든 ML 모델은 상대 예측 오류가 상당히 낮습니다(<15%) wow !

 

3) Nonlinear ML Models with Network Features:

훈련 데이터 세트의 알려진 네트워크에 네트워크 기능이 있는 예측 모델의 성능은 One-HotEncoding을 사용한 것과 거의 동일(표 II 참조).

 

 

VII. RELATED WORK

  • 딥러닝 프레임워크별 벤치마크

T. Ben-Nun, M. Besta, S. Huber, A. N. Ziogas, D. Peter, and T. Hoefler, “A modular benchmarking infrastructure for high-performance and reproducible deep learning,” CoRR, vol. abs/1901.10183, 2019. [Online]. Available: http://arxiv.org/abs/1901.10183

  • (클러스터내 DL 작업의 턴어라운드 시간을 개선하는 스케쥴러)

 

 

 

 

 

ABSTRACT

지리적으로 분산된 클라우드 지역에 저장된 데이터를 가장 저렴한 비용으로 처리하기위한 클라우드 네이티브 데이터 분석엔진을 제안,4개 지역 공용 클라우드 설정에 대한 의사 결정 지원 쿼리의 경우 비용이 15.1% 감소했다.

INTRODUCTION

  • 보통 지리적으로 가까운 region에서 더 빠르기 때문에 여러 기업에서는 region별로 서비스를 제공한다.
  • 예를들어서 아시아에 저장된 고객리스트, 미국에 저장된 고객 리스트등 흩어진 데이터들을 모아서 분석하기위해 , 다중 regions 에 포함된 데이터들에 대해 분석쿼리를 실행하는것은 비싸고 비효율적
  • 여기서 문제가 발생 : 여러 region에 걸친 데이터들을 모두모아 단일 지역에 복제하기위해 옮겨야하는데 추가적인 전송비용 + 데이터 저장비용이 발생, 또 시간적으로도 매우 많은 시간이 걸림 (ex: 케이프타운 region → 시드니리전으로 1gb 전송하는데 평균5분걸림)
  • 목표 : 비용 최적화
  • **대역폭과 대기시간을 고려한 네트워크를 통한 작업배치에 대한 연구 관련Suraj Pandey, Adam Barker, Kapil Kumar Gupta, and Rajkumar Buyya. 2010. Minimizing Execution Costs when Using Globally Distributed Cloud Services. In 2010 24th IEEE International Conference on Advanced Information Networking and Applications. 222–229. https://doi.org/10.1109/AINA.2010.30
  • Tarek Elgamal. 2018. Costless: Optimizing cost of serverless computing through function fusion and placement. In 2018 IEEE/ACM Symposium on Edge Computing (SEC). IEEE, 300–312.
  • **JCT 최적화 관련Raajay Viswanathan, Ganesh Ananthanarayanan, and Aditya Akella. 2016. CLARINET: WAN-Aware Optimization for Analytics Queries. In 12th USENIX Symposium on Operating Systems Design and Implementation (OSDI 16). USENIX Association, Savannah, GA, 435–450. https://www.usenix.org/conference/osdi16/ technical-sessions/presentation/viswanathan
  • Qifan Pu, Ganesh Ananthanarayanan, Peter Bodik, Srikanth Kandula, Aditya Akella, Paramvir Bahl, and Ion Stoica. 2015. Low Latency Geo-Distributed Data Analytics. SIGCOMM Comput. Commun. Rev. 45, 4 (Aug. 2015), 421–434. https://doi.org/10.1145/2829988.2787505

이러한 문제를 해결하고 목표를 달성하기 위해 살펴보아야할 특징들과 발생가능한 문제점들

  • region 별로 다른 가격 ( EC2 m5.2xlarge 인스턴스 비용은 버지니아 북부 지역보다 상파울루 지역에서 약 59% 더 비싸다)
  • region 별로 다른 데이터 전송비용 (아프리카 및 남미와 같은 대륙에서 데이터를 전송하는 경우 AWS의 경우 북미에서 전송하는 비용보다 최대 13배 더 비싸다)
  • 데이터 전송 시간은 region 을 이동할때 10배 이상이며 항상 변동된다.
  • 분석 쿼리를 실행하는 데 몇 시간이 걸리는 것이 일반적이다.
  • 데이터 세트의 크기와 가용성은 언제든지 변경가능

2 SYSTEM ARCHITECTURE

  • 비용최적화라는 목표를 위해, region별로 비용과 성능에 영향을 미치는 모든 요소들을 지속적으로 모니터링하고 주어진 JCT 요구사항에 따라 최대한 비용 효율적인 실행계획을 도출하려고자함 ( = cross-region analytics job 을 가지고 가격 효율적인 plan 을 찾는다 )

Status retriever

  • 각 리전마다 job scheduling 에 대한 필수정보들을 수집하고 제어하는 status retriever가 있다.
  • 이것이하는일은b) 다른 region과 주기적으로 통신하여 네트워크 대역폭내역 수집 (대역폭이 중요한 이유:c) 해당 지역 데이터세트의 metadata 수집
  • we may want to set a limit on job completion time)
  • a) api를 통해 각 cloud vendor 로 부터 가격 책정

→ 가장 중요한 parameters 는 region 별 데이터 전송가격과 각 지역별로 컴퓨팅 리소스가격이다.

  • 모든 region의 status retriever 는 p2p 네트워크를 통해 데이터를 동기화해야할 각 지역의 작업 스케쥴러가 결정을 내릴 충분한 정보를 수집해준다.

Job scheduler

  • Spark SQL 에서 Catalyst optimizer 와 동일한 역할을 함(Spark SQL에서는 Catalyst Optimizer가 최적화를 대신해준다)
  • 소스데이터셋의 메타데이터와 데이터 쿼리를 입력으로 받아서 물리적 실행 계획을 생성
  • 또한 설계에서 계획을 선택할 때 비용과 네트워크 대역폭을 고려.대부분 작업 배치 및 중간 결과가 로컬 I/O 작업 대신 지배적인 요소가 됩니다. (?)

Job manager

  • Job manager 는 Job scheduler 에 의해 생성된 현재 실행계획과 각 Job에 대한 해당작업상태를 유지, 그리고 다른 region에 execution plan과 다른 job plan을 전파합니다.
  • 각 job manager는 execution plan 에 따라 하나이상의 하위작업을 실행한다
  • 이작업이 완료되면 작업 관리자는 작업 스케쥴러를 호출해서 재평가하고 작업상태와 잠재적인 계획변경을 브로드캐스트한다
  • 변경된 계획으로 인해 작업관리자가 하위작업실행을 중단할수 있다.

Task executor

  • computes resources로 이루어져있다.
  • It is built on top of existing cloud offerings to remove the resource constraints of some previous works [12]. Because there is no stable access pattern, and each job requires a different amount of resources, leveraging serverless functions (e.g., AWS Lambda[2]) as the main executor improves resource utilization [14]. Using spot VM instances to run the queries may save cost when incoming workloads can be well predicted.

Transient datastore

  • 하위 작업의 결과는 임시 데이터 저장소에 저장됩니다. 임시 데이터는 나중 단계에서 사용될 수 있으므로 다음 하위 작업으로 전달된 직후에 삭제되지 않습니다. 작업 관리자는 데이터 저장소를 정기적으로 스캔하여 일정 시간이 지나면 실행 계획에서 참조하지 않는 임시 데이터를 식별하고 불필요한 저장 비용을 피하기 위해 제거합니다.

3 PRELIMINARY RESULTS

  • 제안된 시스템의 효율성을 검증하기 위해 AWS에서 실험을 진행
  • 10GB의 TPC-DS[16] 데이터 세트를 생성. 데이터 세트 중 한 region의 Amazon S3 [1] 버킷에 4개의 비교적 작은 테이블을 놓고 4개 region 모두에 큰 테이블을 고르게 배포했습니다.
  • We simulated Query 7 of TPC-DS test suite in Python programs on EC2 c5d.2xlarge spot instances.
  • 4가지 전략
    1. Aggregation ) 모든 데이터를 비용적은 region으로 몰아넣고 모든 계산수행
    2. In-place ) 데이터이동 X , 각 region 에서 가능한 많은 계산을 수행한다음, 해당 영역 중 하나에서 중간결과를 집계 (지역별로 컴퓨팅 가격이 다르다는걸 고려하지 않음)
    3. Optimized In-place ) 각 region 마다 계산수행하기전에 작은 테이블을 모든 region 에 배포(최적화)(the WAN-usage optimal solution)
    4. Hybrid a+c ) 컴퓨팅및 데이터 전송가격으로 결정 (이게 가장좋은 결과를 도출) - 15프로나 좋아짐 가격만 따지면 가장좋은 방법이됨.
    • ** WAN  
      • WAN 최적화가 중요한 이유?다양한 비즈니스 프로세스가 느린 네트워크의 영향을 받습니다. 직원이 파일에 액세스하는 것과 같은 간단한 작업도 허용할 수 없을 정도로 느려질 수 있습니다. 네트워크가 끌리는 경우 비즈니스 전체 파일 관리자를 로드하는 데 시간이 걸리고 파일을 여는 데 더 오래 걸릴 수 있습니다. 2분의 작은 작업처럼 보이지만 이러한 문제는 빠르게 누적됩니다.
      • 한편 관리자는 비효율적이고 대기 시간이 긴 네트워크 인프라와 싸우는 경우 네트워크를 효과적으로 관리 및 모니터링하고 네트워크 보안을 보장하는 데 어려움을 겪을 수 있습니다. WAN 최적화는 잠재적으로 관리자( 및 해당 소프트웨어 도구) 가 모든 장치와 최종 사용자를 보다 효과적으로 보호 할 수 있도록 합니다 .
      • 기업은 클라우드 컴퓨팅, 애플리케이션 및 웹 포털과 같은 기타 네트워크 전체 기술의 사용 증가로 인해 WAN 설정에 대한 압박을 점점 더 많이 받고 있습니다. 이러한 복잡성과 볼륨을 사전에 관리하지 않으면 네트워크 속도 저하가 주요 문제가 될 수 있으므로 WAN 전반에 걸친 관련 트래픽 증가 는 WAN 최적화를 더욱 중요하게 만듭니다.
      • WAN 최적화에는 더 많은 대역폭을 수신하기 위해 네트워크의 특정 부분에 우선 순위를 지정하는 작업이 포함됩니다. 예를 들어 중요한 데이터 처리 작업과 관련된 네트워크 부분에 더 많은 처리량과 대역폭을 할당하여 작업이 빨리 완료되도록 할 수 있습니다. 네트워크에 대한 물리적 또는 논리적 변경을 통해 많은 WAN 개선을 달성할 수 있습니다.
      • https://ledgku.tistory.com/17

4 DISCUSSION(고찰)

Challenge#1 Design an efficient job scheduling algorithm.

  • Catalyst같은 기존 쿼리 옵티마이저는 최상의 실행계획을 검색하는데, 단점으로는 실행시간이 너무많이 걸리고 상당한 오버헤드발생가능성이 있다.
  • 또 실제비용과 네트워크대역폭을 고려하면 문제가 더 복잡해진다
  • 이렇듯 이런 단점을 해결할 빠르게 찾을수 있는 알고리즘이 필요함

Challenge#2 Estimate required resources for subtasks. Both

  • 스팟 vm과 서버리스 모두 일정수준의 프로비저닝이 필요한데 오버프로비저닝,언더프로비저닝 모두 피해야함.
  • 메모리를 적당히 사용하기위해 sub 잡작업에 필요한 최소메모리추정을 위해 프로그램 분석기술을 적용가능

Challenge#3 Manage job states between regions

  • 교차지역 데이터 분석 엔진은 내결함성이 있어야함.
  • 모든 작업상태는 작업관리자간에 공유됨
  • region의 작업관리자가 제대로 작동하지않으면 다른 region에서 알아채고 인계받아야함
  • 한마디로 문제가 생긴다면 기존작업을 다른지역으로 마이그레이션해야함

Challenge#4 Avoid unnecessary execution plan switchin

  • 런타임에 새로운 실행계획이 너무자주 발생하지않도록 함

웹에서 input 데이터를 API Gateway 로 보내려고 AJAX를 사용했다.

아래 코드는 웹에서 클릭 버튼을 눌렀을때, input 데이터들을 api 로 전달해주고 + output 데이터들을 받아오는 Funtion 이다

index.js

function clickclick(){
    let form = $("#ajax-upload-form");
    let formData = new FormData(form[0]);

    formData.append('inputdata_one', $("#inputdata_one").val());
    formData.append('inputdata_two', $("#inputdata_two").val());
	//formData 에 전달해줄 INPUT 데이터값들을 추가로 붙여준다. 

    this.result = []
    $.ajax({
    type: "POST",
    url: 'https://vvvvvv.execute-api.us-east-1.amazonaws.com/pp/predict',  //api gateway URL
    header: {
        "Content-Type": "application/json",	//Content-Type 설정
        "X-HTTP-Method-Override": "POST",
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST',
        'Access-Control-Allow-Headers': '*',
        'Access-Control-Allow-Age': 3600
    },
    dataType: "json",
    data: formData,
    AccessControlAllowOrigin: '*',
    crossDomain: true,
    contentType: false,
    async: false,
    enctype: 'multipart/form-data',
    processData: false,

    success: function (data, status) { //람다에서 제대로 잘 돌아왔을때,
        let result = data['body'] //API 에서 건너온값 data 중 'body'부분만 솎아낸다
        result = result.replace("\"", ""); 
        result = result.split('&');  //result가 여러개라 &로 구분하였기 때문에 끊어줌
        
        console.log("data : ", data) //잘들어온건지 확인하고 싶어서
        console.log(result[0]) //잘나눠졌는지 확인하고 싶어서
    },
    error: function (e) {
        console.log("ERROR : ", e);
        $("#btnSubmit").prop("disabled", false);
        alert(e.message);
    }
    });
}

 

index.html 일부 (파일올리고 제출하는 부분)

                    <form method="POST" enctype="multipart/form-data" id="ajax-upload-form" name="upload-form">
                        <input type="file" name="upload-file" id="upload-file" onchange="loadFile(this)" required>
                        <input type="button" value="Submit" id='ajax-submit'>
                    </form>

 

이렇게 웹에서 input 데이터들을 api 를 통해서 람다에서 받아보면 아래처럼 data가 들어온다.

 

body = "------WebKitFormBoundaryWvqm9JrHYYK3TJSv\r\nContent-Disposition: form-data; name=\"upload-file\"; filename=\"sample.json\"\r\nContent-Type: application/json\r\n\r\n[{\"A\":1278.751,\"B\":7.168,\"C\":4025.032,\"D\":9.056,\"E\":56.962,\"F\":4646.806}]\r\n------WebKitFormBoundaryWvqm9JrHYYK3TJSv\r\nContent-Disposition: form-data; name=\"inputdata_one\"\r\n\r\nGGGGGGGG\r\n------WebKitFormBoundaryWvqm9JrHYYK3TJSv\r\nContent-Disposition: form-data; name=\"inputdata_two\"\r\n\r\n3333333\r\n------WebKitFormBoundaryWvqm9JrHYYK3TJSv--"

 

위는 data['body'] 부분이다.

인풋파일3개 (json 파일1개, 입력값2개) 가 잘 들어있는지 확인해보자면,

 

[{\"A\":1278.751,\"B\":7.168,\"C\":4025.032,\"D\":9.056,\"E\":56.962,\"F\":4646.806}] 이부분은 input 파일인 sample.json 안의 내용이다.

 

그외에 두가지 인풋이 더 있었는데 잘 살펴보면

inputdata_one : GGGGGGGG

inputdata_two : 3333333

로 들어가있음을 확인할수 있다.

 

해당 인풋파일 3개를 추출해내기 위해서 사용한 파싱방법

    json_feature = json.loads(body[body.find('['): body.rfind(']')+1]) 
    // json 파일안의 내용 뽑아내기
    
    body = body.replace('\n',"")
    body = body.replace('\r',"")
    body = body.replace('-',"")
	
    INPUTTWO = (body[body.find('inputdata_one')+14: body.rfind('WebKitFormBoundary')])
    body = (body[: body.rfind('WebKitFormBoundary')])
    INPUTONE = int(body[body.find('inputdata_one')+14: body.rfind('WebKitFormBoundary')])

 

+ Recent posts