<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Junbum Lee]]></title><description><![CDATA[Junbum Lee]]></description><link>https://blog.beomi.net</link><generator>RSS for Node</generator><lastBuildDate>Fri, 08 May 2026 13:53:08 GMT</lastBuildDate><atom:link href="https://blog.beomi.net/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[VSCode에서 Format on Save가 동작하지 않는 것 처럼 보일 때]]></title><description><![CDATA[VSCode의 Format on Save
VSCode를 쓰고 프로젝트를 설정한 뒤, "Format on Save" 옵션을 아래와 같이 켜 둘 경우, 
파일 내 변화가 발생한 뒤 저장할 경우 사전에 설정된 방식으로 포맷팅을 진행한다.

위 사진과 같이, python 환경이 설정된 상태에서는, autopep8이나 black와 같은 Formatter를 설치하도록 안내한다.
*단, 해당 기능은 VSCode Python Extension이 설치되어있고 ...]]></description><link>https://blog.beomi.net/vscode-format-on-save</link><guid isPermaLink="true">https://blog.beomi.net/vscode-format-on-save</guid><category><![CDATA[Visual Studio Code]]></category><category><![CDATA[Python]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Junbum Lee]]></dc:creator><pubDate>Tue, 03 May 2022 01:23:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1651478847798/2Yh5jZ-i8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-vscode-format-on-save">VSCode의 Format on Save</h1>
<p>VSCode를 쓰고 프로젝트를 설정한 뒤, "Format on Save" 옵션을 아래와 같이 켜 둘 경우, 
파일 내 변화가 발생한 뒤 저장할 경우 사전에 설정된 방식으로 포맷팅을 진행한다.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651479028557/taemiCMJg.png" alt="VSCode의 Format on Save 옵션, Python 파일 예시" /></p>
<p>위 사진과 같이, python 환경이 설정된 상태에서는, <code>autopep8</code>이나 <code>black</code>와 같은 Formatter를 설치하도록 안내한다.</p>
<p>*단, 해당 기능은 VSCode Python Extension이 설치되어있고 &amp; 해당 프로젝트(폴더)에 대해 Python 환경(어떤 경로의 python을 사용하는지)이 설정되어있어야 한다.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651478847798/2Yh5jZ-i8.png" alt="VSCode에서 python 포매터가 설정되어있지 않은 경우, 설치 안내 팝업이 뜬다." /></p>
<blockquote>
<p><code>black</code>이 가장 빡빡한 편이라, 여러 사람이 협업하는 환경에서는 가장 좋은 듯 하다.(개인적 경험)</p>
</blockquote>
<h1 id="heading-formatter-auto-format">Formatter도 설치되어있는데, 왜 Auto format이 안되지?</h1>
<p>간혹 환경에 따라 formatter가 설치되어있는데도 Format on Save 기능이 동작하지 않는 경우가 있다.</p>
<p>이 경우는 많은 경우, VSCode에 내장된 Formatter와 외부(npm등)에 설치된 Formatter가 모두 존재해, 어떤 Formatter를 사용할지 지정되지 않았기 때문인 경우다.</p>
<p>이때는, 아래와 같이 커맨드 팔레트를 열어 <code>&gt; Format Document</code> 메뉴를 선택하면, VSCode에 내장된 포매터 혹은 외부 포매터 중에서 선택할 수 있다.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651540758791/t_Pn1nLhW.png" alt="image.png" /></p>
]]></content:encoded></item><item><title><![CDATA[개발환경 / 배포환경별 API URL 바꾸기 (feat. React & axios)]]></title><description><![CDATA[process.env
React도 여타 node.js를 사용한 개발과 같이, process.env 오브젝트를 통해 현재 node.js가 실행되고 있는 환경변수를 가져올 수 있다.
한편, create-react-app을 통해 제작한 앱의 경우에는 .env을 지원한다.
.env가 항상 불러오는 전체 용도이고,
.env.development는 npm start를 통해 실행할 경우 불러오는 경우이며,
.env.production는 npm run bui...]]></description><link>https://blog.beomi.net/api-url-feat-react-and-axios</link><guid isPermaLink="true">https://blog.beomi.net/api-url-feat-react-and-axios</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[APIs]]></category><category><![CDATA[Programming Tips]]></category><dc:creator><![CDATA[Junbum Lee]]></dc:creator><pubDate>Sun, 01 May 2022 04:46:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/UYsBCu9RP3Y/upload/v1651379794586/_D3rKIWHy.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-processenv">process.env</h1>
<p>React도 여타 node.js를 사용한 개발과 같이, <code>process.env</code> 오브젝트를 통해 현재 node.js가 실행되고 있는 환경변수를 가져올 수 있다.</p>
<p>한편, <code>create-react-app</code>을 통해 제작한 앱의 경우에는 <code>.env</code>을 지원한다.</p>
<p><code>.env</code>가 항상 불러오는 전체 용도이고,</p>
<p><code>.env.development</code>는 <code>npm start</code>를 통해 실행할 경우 불러오는 경우이며,</p>
<p><code>.env.production</code>는 <code>npm run build</code>를 실행할 경우 빌드 타임에 env를 가져오는 방식이다.</p>
<h1 id="heading-env"><code>.env</code> 문법</h1>
<pre><code class="lang-bash"><span class="hljs-comment"># .env.production</span>
REACT_APP_API_URL=<span class="hljs-string">"https://some-api.test.com"</span>
</code></pre>
<pre><code class="lang-bash"><span class="hljs-comment"># .env.development</span>
REACT_APP_API_URL=<span class="hljs-string">"http://localhost:8000"</span>
</code></pre>
<p>위와 같이 <code>REACT_APP_</code> 로 사전 정의된 이름으로 시작해야, React에서는 "아 이게 react용이구나" 라고 자체적으로 관리하는 환경변수로 인식한다.</p>
<p>한편, 위 변수 이름은 <code>process.env.REACT_APP_API_URL</code> 와 같이 풀네임으로 사용해야 해당 값을 불러올 수 있다.</p>
<p>또한, 해당 환경 변수값은 코드상에서는 <code>process.env.~~</code> 형식이지만 <code>npm start</code>등 React 빌드가 진행된 이후에는 const value로 동작한다.</p>
<h1 id="heading-react-api-with-axios">React에서 API 주소 with Axios</h1>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">"axios"</span>;

<span class="hljs-comment">// axios.defaults.baseURL = "http://localhost:8000";</span>
axios.defaults.baseURL = process.env.REACT_APP_API_URL;
</code></pre>
<p>따라서, API 주소를 환경에 따라 바꾸기 위해서는 위처럼 고정된 string으로 넣는 대신, <code>process.env.REACT_APP_API_URL</code>로 넣어주면 해결된다.</p>
]]></content:encoded></item><item><title><![CDATA[VSCode Bouncing Icon on MacOS Dock 해결하기]]></title><description><![CDATA[Issue
VS Code를 띄우고 '창을 켜기만 하면' Bouncing Icon(macos)이 하나가 더 뜨고 '응답없음' 상태가 되는 버그.
Solution
Ref: https://github.com/microsoft/vscode/issues/138838#issuecomment-991354259
spellright 을 제거하자.
아래그림의 익스텐션을 Disable/삭제 해주면 문제가 해결된다.]]></description><link>https://blog.beomi.net/vscode-bouncing-icon-on-macos-dock</link><guid isPermaLink="true">https://blog.beomi.net/vscode-bouncing-icon-on-macos-dock</guid><category><![CDATA[macOS]]></category><category><![CDATA[Visual Studio Code]]></category><dc:creator><![CDATA[Junbum Lee]]></dc:creator><pubDate>Thu, 28 Apr 2022 02:26:51 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-issue">Issue</h1>
<p>VS Code를 띄우고 '창을 켜기만 하면' Bouncing Icon(macos)이 하나가 더 뜨고 '응답없음' 상태가 되는 버그.</p>
<h1 id="heading-solution">Solution</h1>
<p>Ref: https://github.com/microsoft/vscode/issues/138838#issuecomment-991354259</p>
<p><code>spellright</code> 을 제거하자.</p>
<p>아래그림의 익스텐션을 Disable/삭제 해주면 문제가 해결된다.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1651112688802/4OhjC7MRe.png" alt="SpellRight Extension(for VS Code)" /></p>
]]></content:encoded></item><item><title><![CDATA[딥러닝 API, GPU+도커로 서빙하기 (feat. on premise)]]></title><description><![CDATA[COG?
COG(Github)는 PyTorch와 같은 딥러닝 모델을 서빙하기 위해 나온 🐳도커 이미지 빌드 툴로, 간단한 YAML 파일과 Python 패키지 설정만으로 FastAPI에 기반한 웹 API를 제작해준다.
🤗 Transformers 라이브러리로 사용해보기
COG Yaml 파일
cog yaml 파일은 아래와 같은 형식을 가진다. 가장 주요한 특징은 gpu: true로 옵션을 제공할 경우, 아래 python_packages에 torc...]]></description><link>https://blog.beomi.net/api-gpu-feat-on-premise</link><guid isPermaLink="true">https://blog.beomi.net/api-gpu-feat-on-premise</guid><category><![CDATA[nlp]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Deep Learning]]></category><dc:creator><![CDATA[Junbum Lee]]></dc:creator><pubDate>Mon, 25 Apr 2022 08:49:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/jOqJbvo1P9g/upload/v1650872280380/o32OrzpJh.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-cog">COG?</h2>
<p><a target="_blank" href="https://github.com/replicate/cog">COG(Github)</a>는 PyTorch와 같은 딥러닝 모델을 서빙하기 위해 나온 🐳도커 이미지 빌드 툴로, 간단한 YAML 파일과 Python 패키지 설정만으로 FastAPI에 기반한 웹 API를 제작해준다.</p>
<h2 id="heading-transformers">🤗 Transformers 라이브러리로 사용해보기</h2>
<h3 id="heading-cog-yaml">COG Yaml 파일</h3>
<p>cog yaml 파일은 아래와 같은 형식을 가진다. 가장 주요한 특징은 <code>gpu: true</code>로 옵션을 제공할 경우, 아래 <code>python_packages</code>에 <code>torch</code>나 <code>tensorflow</code>와 같은 DL 패키지가 적혀 있는 경우 해당 패키지에 적합한 CUDA, cuDNN이 사전에 설정된 Ubuntu기반 이미지(NVIDIA가 제공)를 불러와서 빌드를 진행해준다는 점이다.</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># cog.yaml</span>
<span class="hljs-attr">build:</span>
  <span class="hljs-attr">gpu:</span> <span class="hljs-literal">true</span>
  <span class="hljs-attr">python_version:</span> <span class="hljs-string">"3.9"</span>
  <span class="hljs-attr">python_packages:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">"torch==1.10.0"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">"transformers==4.18"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">"sentencepiece==0.1.96"</span>
    <span class="hljs-bullet">-</span> <span class="hljs-string">"protobuf==3.20.1"</span>
<span class="hljs-attr">predict:</span> <span class="hljs-string">"predict.py:Predictor"</span>
</code></pre>
<blockquote>
<p>주의: 위 <code>python_packages</code>은 정확히 <code>==</code> 으로 버전을 pin해줘야 동작한다. <code>&lt;</code>등의 뭉뚱그려진 Requirements는 빌드를 거절하더라.</p>
</blockquote>
<p>위와 같은 Yaml 파일로 설정을 할 경우, Ubuntu 18.04 LTS에 CUDA 11.1이 설치된 이미지를 Base 이미지로 사용하고, 그 위에 PyTorch를 1.10(CUDA 11.1)을 설치한다.</p>
<p>다만, <code>python_version</code>을 지정하는 경우 해당 파이썬 버전을 <code>.tar.xz</code> 소스로 받아 설치하는 과정이 있어, 첫 빌드 시간이 꽤나 걸린다는 단점이 있다.
따로 파이썬 버전을 지정하지 않는 경우에는 시스템에 내장된 버전을 사용하는 듯 하다. (Ubuntu 18.04는 Python 3.7 등)</p>
<h3 id="heading-cog">COG 파이썬 파일</h3>
<p>아래 파이썬 파일을 통해 실제 모델을 서빙하게 된다.
Huggingface Transformers 라이브러리를 사용한다고 별다른 차이가 발생하지는 않는다.</p>
<pre><code class="lang-python"><span class="hljs-comment"># predict.py</span>
<span class="hljs-keyword">from</span> cog <span class="hljs-keyword">import</span> BasePredictor, Input, Path
<span class="hljs-keyword">import</span> torch
<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> pipeline
<span class="hljs-keyword">import</span> json


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Predictor</span>(<span class="hljs-params">BasePredictor</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">setup</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""Load the model into memory to make running multiple predictions efficient"""</span>
        self.pipe = pipeline(
            <span class="hljs-string">"text-generation"</span>,
            model=<span class="hljs-string">"beomi/kcgpt2"</span>,
            device=<span class="hljs-number">0</span> <span class="hljs-keyword">if</span> torch.cuda.is_available() <span class="hljs-keyword">else</span> <span class="hljs-number">-1</span>,
        )

    <span class="hljs-comment"># The arguments and types the model takes as input</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">predict</span>(<span class="hljs-params">self, x: str = Input(<span class="hljs-params">description=<span class="hljs-string">"문장을 입력해 주세요."</span></span>)</span>) -&gt; str:</span>
        <span class="hljs-string">"""Run a single prediction on the model"""</span>
        output = self.pipe(
            x,
            do_sample=<span class="hljs-literal">True</span>,
            top_p=<span class="hljs-number">0.9</span>,
            no_repeat_ngram_size=<span class="hljs-number">2</span>,
            <span class="hljs-comment"># early_stopping=True,</span>
            <span class="hljs-comment"># max_new_tokens=150,</span>
            num_return_sequences=<span class="hljs-number">20</span>,
            max_length=<span class="hljs-number">150</span>,
        )
        <span class="hljs-keyword">return</span> json.dumps(output, ensure_ascii=<span class="hljs-literal">False</span>, indent=<span class="hljs-number">2</span>)
</code></pre>
<p>다만, 위와 같이 Transformers Hub에서 모델을 다운받아야 하는 경우, 해당 모델 파일을 도커 이미지에 함께 포함하지 않아서, 매 실행시마다 Hub에서 다운받는 문제가 있다.</p>
<p>이 문제는 두 가지 방법이 있는데, 상황에 따라 적절히 선택하면 될 것 같다.</p>
<ol>
<li>도커 실행시 Huggingface 라이브러리 캐싱 폴더를 Volume으로 마운트 (도커 레벨에서 재활용)</li>
<li>모델을 애초에 다운받아서, 도커 빌드시에 포함 (도커 이미지에 포함시키기)</li>
</ol>
<p>일반적으로는 PLM을 Finetune한 사내 모델을 사용하기 때문에, 2번과 같이 로컬 폴더에서 도커 이미지 빌드 시점에 통합해서 사용하는 것이 일반적일 것 같다.</p>
<h3 id="heading-7j206647keaioq1veq4sa">이미지 굽기</h3>
<p>위와 같이 준비가 완료되면, 아래와 같이 빌드를 진행할 수 있다.</p>
<pre><code class="lang-bash">cog build -t cog-test
</code></pre>
<h3 id="heading-7j206647keaioylpo2wie2vmoq4sa">이미지 실행하기</h3>
<p>이미지가 준비되면, 해당 도커 이미지는 내부 5000포트로 FastAPI가 서빙되고 있다.</p>
<blockquote>
<p>해당 FastAPI는 Uvicorn을 통해 ASGI로 서빙된다.</p>
</blockquote>
<p>이때, <code>--gpus 1</code>와 같이 GPU 옵션을 제공해 넘겨주면 (기존 predict.py 코드가 GPU를 지원한다면) 웹 API 서비스 역시 GPU 가속을 지원해준다.</p>
<pre><code>docker run <span class="hljs-operator">-</span>it <span class="hljs-operator">-</span>p <span class="hljs-number">5000</span>:<span class="hljs-number">5000</span> <span class="hljs-operator">-</span><span class="hljs-operator">-</span>gpus <span class="hljs-number">1</span> cog<span class="hljs-operator">-</span>test
</code></pre><blockquote>
<p>참고: <code>--gpus</code>옵션은 '갯수'라서, 1=1개, 2=2개,.. 이다. 만약 특정 idx의 GPU를 지정하려면 <code>--gpus '"device=0,2"'</code>같이 특정 idx(0,2번)의 GPU를 지정해줄 수 있다. device 번호로 지정은 상당히 귀찮다..</p>
</blockquote>
<h2 id="heading-cog-ui">COG UI</h2>
<p>COG는 웹 Swagger 형식으로 UI를 지원해준다. 간단한 POST 테스트를 웹 상에서도 진행가능!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1650876178608/1-0f4EP5c.png" alt="COG에서 제공해주는 Swagger UI" /></p>
<h2 id="heading-7isx64ql">성능</h2>
<p>성능은 차이가 아예 없다. 모델 컴파일 작업이나 경량화 작업 혹은 최적화 작업이 없이, 기존의 모델 forward 코드를 그대로 가져다 쓸 수 있다는 것이 장점이자 단점.</p>
<h3 id="heading-7ian64eio2wpeydgsdrnbzsnbtruizrn6zrpqw">속도 향상 라이브러리</h3>
<p>성능 향상을 위해서는 여러가지 옵션을 생각해볼 수 있을 듯 하다.</p>
<p><a target="_blank" href="https://github.com/nebuly-ai/nebullvm">nebullvm</a>와 같은, ONNX 등을 통한 CPU/GPU상에서 서빙을 가속하는 라이브러리와 함께 사용한다면, 보다 라이브에 태울 수 있는 수준의 속도가 나오지 않을까.</p>
<h2 id="heading-reference">Reference</h2>
<ul>
<li>COG: https://github.com/replicate/cog</li>
</ul>
]]></content:encoded></item></channel></rss>