본문 바로가기

카테고리 없음

Amazon SageMaker Studio Lab vs Google Colab

개요

Jupiter Notebook을 사용할수 있는 Lab 환경을 무료로 제공 해주는 대표적인 두가지 서비스입니다.
Google에서는 colab으로 예전 부터 제공해왔고, Amazon도 21년 12월 부터 제공하기 시작했습니다.

비교

Google CoLab은 Google Drive로 부터 연동되어서 접근성이 무척 좋고, 자원 할당도 잘 됩니다.
Amazon SageMaker Studio Lab는 일단 별도 계정을 신청해야 하며, 승인이 나야 사용 가능합니다.
승인과정은 하루 정도 걸렸습니다. 다만 Google Drive 같은 스토리지 연동이 없는 점이 조금 아쉽지만,
이 때문인지 영구 스토리지 50GB를 제공합니다.

CoLab의 경우 기본적으로 5GB를 제공하지만 자원이 종료되면 모두 초기화 됩니다. 처음에 결과물이 사라져서 당황했었죠.
이 때문에 자원 종료후에도 데이터 저장 유지가 필요한 경우 Google Drive를 마운트 해서 써야 하는데 이 부분이 조금 번거로운 점입니다.
해당 부분 코드는 다른 환경에서 문제가 되기 때문이죠.

성능 비교

성능 적인 부분은 간단히 테스트 했을때 Amazon SageMaker Studio Lab이 더 좋게 나왔습니다.
사용중 간단한 테스트라서 전체 성능을 말해주지는 않고 있고, 단순히 참고 해주시면 좋겠습니다.

일단 Amazon SageMaker Studio Lab은 최초 실행시 런타임 로딩 시간이 없었습니다.
노트북 시작시 미리 로딩 하는것 같았으며, Restart Kernel도 3-4초 이내로 coLab이 4-5초 대비 조금 더 빨랐습니다.

아래 코드로 베이지안 기준으로 도로 경로 찾는 동일 과정을 수행을 3번 했을 때 평균은 아래와 같습니다.

  • Amazon SageMaker Studio Lab : 194.24초
  • Google Colab : 273.83초

Amazon SageMaker Studio Lab Google Colab 비교 결과
SageMaker Studio Lab이 CPU JOB 기준으로 30% 정도 더 빠르네요.
GPU는 추후 기회 되면 해보겠습니다.

import copy
from shapely.geometry import Point, Polygon
from shapely.geometry.polygon import LinearRing, LineString

def improve_race_line(old_line, inner_border, outer_border):
    '''Use gradient descent, inspired by K1999, to find the racing line'''
    # start with the center line
    new_line = copy.deepcopy(old_line)
    ls_inner_border = Polygon(inner_border)
    ls_outer_border = Polygon(outer_border)
    for i in range(0,len(new_line)):
        xi = new_line[i]
        npoints = len(new_line)
        prevprev = (i - 2 + npoints) % npoints
        prev = (i - 1 + npoints) % npoints
        nexxt = (i + 1 + npoints) % npoints
        nexxtnexxt = (i + 2 + npoints) % npoints
        #print("%d: %d %d %d %d %d" % (npoints, prevprev, prev, i, nexxt, nexxtnexxt))
        ci = menger_curvature(new_line[prev], xi, new_line[nexxt])
        c1 = menger_curvature(new_line[prevprev], new_line[prev], xi)
        c2 = menger_curvature(xi, new_line[nexxt], new_line[nexxtnexxt])
        target_ci = (c1 + c2) / 2
        #print("i %d ci %f target_ci %f c1 %f c2 %f" % (i, ci, target_ci, c1, c2))

        # Calculate prospective new track position, start at half-way (curvature zero)
        xi_bound1 = copy.deepcopy(xi)
        xi_bound2 = ((new_line[nexxt][0] + new_line[prev][0]) / 2.0, (new_line[nexxt][1] + new_line[prev][1]) / 2.0)
        p_xi = copy.deepcopy(xi)
        for j in range(0,XI_ITERATIONS):
            p_ci = menger_curvature(new_line[prev], p_xi, new_line[nexxt])
            #print("i: {} iter {} p_ci {} p_xi {} b1 {} b2 {}".format(i,j,p_ci,p_xi,xi_bound1, xi_bound2))
            if np.isclose(p_ci, target_ci):
                break
            if p_ci < target_ci:
                # too flat, shrinking track too much
                xi_bound2 = copy.deepcopy(p_xi)
                new_p_xi = ((xi_bound1[0] + p_xi[0]) / 2.0, (xi_bound1[1] + p_xi[1]) / 2.0)
                if Point(new_p_xi).within(ls_inner_border) or not Point(new_p_xi).within(ls_outer_border):
                    xi_bound1 = copy.deepcopy(new_p_xi)
                else:
                    p_xi = new_p_xi
            else:
                # too curved, flatten it out
                xi_bound1 = copy.deepcopy(p_xi)
                new_p_xi = ((xi_bound2[0] + p_xi[0]) / 2.0, (xi_bound2[1] + p_xi[1]) / 2.0)

                # If iteration pushes the point beyond the border of the track,
                # just abandon the refinement at this point.  As adjacent
                # points are adjusted within the track the point should gradually
                # make its way to a new position.  A better way would be to use
                # a projection of the point on the border as the new bound.  Later.
                if Point(new_p_xi).within(ls_inner_border) or not Point(new_p_xi).within(ls_outer_border):
                    xi_bound2 = copy.deepcopy(new_p_xi)
                else:
                    p_xi = new_p_xi
        new_xi = p_xi
        # New point which has mid-curvature of prev and next points but may be outside of track
        #print((new_line[i], new_xi))
        new_line[i] = new_xi
    return new_line

    print( "Count of waypoints : %d , XI_I : %d , LINE_I : %d \n" % (len(center_line), XI_ITERATIONS, LINE_ITERATIONS) )
# start along centerline of track
start_time = time.time()
race_line = copy.deepcopy(race_center[:-1]) 

for i in range(LINE_ITERATIONS):
    race_line = improve_race_line(race_line, race_inner_border, race_outer_border)  # Remove "_new" for entire track width
    if (i+1) % 5 == 0: print("", end="\r Iteration of : %d/%d" % (i+1,LINE_ITERATIONS), flush=True)
print("\n Execution time : ", time.time() - start_time)

# need to put duplicate point race_line[0] at race_line[-1] to make a closed loops
loop_race_line = np.append(race_line, [race_line[0]], axis=0)

# These should be the same
print("계산된 카운트 수가 같아야 합니다.: ", (np.asarray(center_line).shape, loop_race_line.shape))
print("트랙의 중앙선 길이: %0.2f" % l_center_line.length)
print("새로 계산된 레이싱라인 길이: %0.2f" % LineString(loop_race_line).length)

서비스 장단점 비교

현실적인 관점에 무료 버전의 장단점 비교는 아래와 같습니다.

기능/특성 Amazon SageMaker Studio Lab Google CoLab
DISK 50GB 제공 , 영구 유지 , 매뉴얼 초기화 가능 5GB 제공 , 런타임 종료시 초기화
외부 스토리지 & 협업 번거로움 (로컬과 동일) Goolge Drive 에서 실행히 자동 실행, Mount도 가능
런타임 제한 연속 CPU:12시간 GPU:4시간 & 일 8시간 제한 무료 사용자: 일 12시간
기본 라이브러리 기본 라이브러리와 AWS 관련 라이브러리가 포함됨 기본 라이브러리와 Google Cloud 관련 라이브러리가 포함됨
배포 및 서비스화 AWS 인프라를 사용한 모델 배포 및 서비스화 가능 Google Cloud Platform을 사용한 모델 배포 및 서비스화 가능
계정 편의성 별도 계정 필요, 초기 승인 과정 구글 계정 연동
성능 colab 대비 30% 우세 -
자원 할당 바쁜 시간에 거의 안됨 비교적 잘됨

결론

성능은 SageMaker Studio Lab이 좋으나 자원 할당이 잘 안되는 문제와 편의성이 조금 불편하네요.
실제 결론은 둘다 같이 쓰면 됨 입니다.