rust

37 개의 포스트

cloudflare

모든 내부 바이브 코딩 애플리케이션을 한 번의 클릭으로 안전하게 보호하세요 (새 탭에서 열림)

AI로 애플리케이션 개발·배포가 쉬워진 만큼, 직원이 실수로 내부 애플리케이션이나 데이터를 인터넷에 노출할 위험도 커졌다. Cloudflare는 이를 막기 위해 Workers에 Cloudflare Access를 직접 연결해, 애플리케이션 코드나 개발자의 설정에 의존하지 않고 기본적으로 인증을 강제할 수 있도록 했다. 계정 전체, 개별 Worker, 프리뷰 환경에 정책을 적용하고, 코드에서는 별도의 JWT 검증 없이 인증 사용자 정보를 사용할 수 있다. ## Worker 단위로 적용하는 Cloudflare Access - Access를 Worker에 활성화하면 요청이 애플리케이션 코드에 도달하기 전에 인증이 수행된다. - 다음과 같은 접근 경로를 모두 보호할 수 있다. - 커스텀 도메인 - 라우트 - `workers.dev` 서브도메인 - 프리뷰 URL - 기존에는 호스트 이름별로 Access 정책을 설정해야 했기 때문에 새 도메인을 추가할 때마다 정책도 갱신해야 했다. - 이제 정책이 호스트 이름이 아닌 Worker에 연결되므로, 해당 Worker에 연결된 새 도메인과 URL도 자동으로 보호된다. - 보호 범위는 다음 중에서 선택할 수 있다. - 프리뷰 URL만 보호 - 모든 호스트 이름 보호 - 기존 IdP를 연결하거나 특정 이메일 주소, 도메인, 그룹만 허용할 수 있으며, 에이전트에는 서비스 토큰을 사용할 수 있다. ## 계정 전체의 Worker를 기본적으로 비공개 처리 - 계정 수준에서 Access 정책을 설정하면 현재 및 향후 생성되는 모든 Worker가 기본적으로 비공개가 된다. - 정책 적용 범위는 다음과 같이 선택할 수 있다. - 프리뷰 트래픽만 - 프로덕션 트래픽만 - 프리뷰와 프로덕션 모두 - 프로덕션은 공개해야 하지만 개발 중인 배포는 노출되면 안 되는 경우, 프리뷰 전용 정책이 유용하다. - 특정 Worker를 공개해야 한다면 계정 전체 정책을 해당 Worker에서 우회할 수 있다. ## 개별 Worker 정책과 우선순위 - 계정 전체를 잠그지 않고 특정 애플리케이션만 보호하는 것도 가능하다. - Worker 화면의 새로운 Access 탭에서 해당 애플리케이션에 적용되는 정책을 확인할 수 있다. - 여러 정책이 겹칠 경우 우선순위는 다음과 같다. 1. 호스트 이름 정책 2. Worker 정책 3. 계정 정책 ## 코드에서 인증 사용자 정보 확인 - Access가 Worker를 보호하면 요청의 `ctx` 객체에 인증 사용자 정보가 포함된다. - `ctx.access.getIdentity()`를 호출해 다음 정보를 얻을 수 있다. - 이메일 - 이름 - 그룹 - 기존에는 JWT를 직접 파싱하고 서명을 검증한 뒤 클레임을 추출해야 했지만, 이제는 Worker에서 바로 identity 객체를 사용할 수 있다. ```js export default { async fetch(request, env, ctx) { if (!ctx.access) { return new Response("Access required", { status: 403 }); } const identity = await ctx.access.getIdentity(); const email = identity?.email ?? "unknown"; return new Response(`Hello, ${email}`); } }; ``` - 사용자별 화면 구성, 권한 검사, 사용자 단위 감사 로그 등에 활용할 수 있다. ## 로컬 개발 환경에서 인증 사용자 시뮬레이션 - 배포 전에 `wrangler dev`에서 Access 사용자 정보를 테스트할 수 있다. - `wrangler.jsonc`에 개발용 Access identity를 설정한다. ```json { "access": { "dev": { "aud": "my-app", "identity": { "email": "admin@company.com" } } } } ``` - 로컬 요청에서도 `ctx.access.getIdentity()`가 프로덕션과 유사한 identity 객체를 반환한다. - 이메일 주소를 바꿔가며 사용자별 콘텐츠와 권한 동작을 배포 없이 검증할 수 있다. ## 내부 애플리케이션 플랫폼 보호 - Workers for Platforms를 이용하면 여러 애플리케이션을 대규모로 배포할 수 있다. - 각 Worker가 네임스페이스에 배포되고, 모든 요청은 하나의 dispatch Worker를 거친다. - dispatch Worker에 Access 정책을 한 번만 설정하면 이를 통해 배포되는 모든 Worker가 기본적으로 비공개가 된다. - 내부 드래그 앤 드롭 배포 플랫폼처럼 직원용 애플리케이션 플랫폼을 구축할 때 유용하다. ## FL2 기반 요청 처리 구조 - Worker 단위 Access 적용은 Cloudflare의 Rust 기반 모듈형 프록시인 FL2를 기반으로 한다. - Access가 실행되기 전에 요청이 어느 Worker로 라우팅될지 알아야 하므로, Workers 라우팅과 실행 로직을 분리해야 했다. - 라우팅을 Access보다 앞 단계로 이동함으로써 호스트 이름이 아니라 개별 Worker를 기준으로 인증 정책을 적용할 수 있게 되었다. - 기존 NGINX·Lua 기반 FL1 구조에서는 요청 파이프라인의 로직을 앞 단계로 옮기는 작업이 복잡하고 위험할 수 있었지만, FL2가 이를 가능하게 했다. 개발 조직에서는 계정 수준에서 프리뷰 배포를 우선 보호하고, 공개가 필요한 Worker만 명시적으로 예외 처리하는 방식이 실용적이다. 내부 플랫폼을 운영한다면 dispatch Worker에 Access를 적용해 새로 배포되는 모든 애플리케이션을 비공개 상태로 시작하는 것이 안전하다.

cloudflare

Kitesurf 소개: Cloudflare Workers의 V8 격리 환경에서 실행되는 에이전트 우선 브라우저 (새 탭에서 열림)

Cloudflare는 인간이 아닌 AI 에이전트에 최적화된 브라우저가 필요하다고 판단해, Workers 위에서 동작하는 헤드리스 브라우저 **Kitesurf**를 개발했다. Chromium이 제공하는 탭·확장 기능·정밀한 시각 렌더링보다 토큰 수, 확장성, 성능, 비용, 구조화된 콘텐츠 추출을 우선하며, 일반적인 에이전트 작업에서 CPU와 메모리 사용량을 크게 줄이는 것이 목표다. Kitesurf는 Browser Run에서 베타 서비스로 무료 제공된다. ## AI 에이전트에 기존 브라우저가 과한 이유 - Chromium 같은 브라우저 엔진은 인간 사용자를 중심으로 설계됐다. - AI 에이전트에는 다음 기능의 가치가 낮다. - 탭, 테마, 브라우저 확장 기능 - 여러 기기 간 동기화 - 픽셀 단위로 정확한 렌더링 - 부드러운 60fps 스크롤 - 반대로 에이전트에는 다음 요소가 중요하다. - 적은 토큰 수와 효율적인 컨텍스트 사용 - HTML 등 구조화된 콘텐츠 - 높은 처리량과 확장성 - 낮은 CPU·메모리 사용량과 비용 - AI 브라우저의 위협 모델도 인간용 브라우저와 다르다. - 임의의 웹사이트를 방문하는 에이전트는 모든 페이지를 신뢰할 수 없는 입력으로 다뤄야 한다. - 프롬프트 인젝션과 도구 사용 안전성이 핵심 보안 문제가 된다. ## Cloudflare 플랫폼이 가능하게 한 전환점 - Kitesurf는 Cloudflare Workers 위에서 전체적으로 실행된다. - 다음 기술 발전이 복잡한 브라우저 구현을 가능하게 했다. - Workers에서의 성숙한 WebAssembly 지원 - 동적 워커 - SQLite 기반 Durable Objects - 워커 간 RPC - 서비스 바인딩 - 향상된 Node.js 호환성 - 더 높은 실행 한도 - AI 에이전트용 브라우저 자동화 수요가 커지면서, 기존 Chromium 인스턴스를 에이전트마다 제공하는 방식의 비용 문제가 부각됐다. - Kitesurf는 이러한 환경에서 더 작고 저렴한 브라우저 실행 모델을 제공하려는 시도다. ## 초기 구현과 AI 활용 - 출발점은 Rust로 작성된 AI 자동화용 헤드리스 엔진 **obscura**였다. - Cloudflare 팀은 AI 에이전트의 도움을 받아 이를 Workers로 포팅했다. - 초기 결과는 불완전했지만, 명확한 실행 계획과 성공 조건을 제공하자 AI가 반복적으로 구현·검증하며 작동하는 프로토타입을 만들 수 있었다. - 이후 프로토타입을 기반으로 실제 대규모 서비스에 필요한 구조와 품질 기준을 마련했다. ## 테스트를 중심으로 한 개발 방식 - 복잡한 브라우저를 AI의 도움으로 빠르게 개발하려면, 구현 속도뿐 아니라 결과 품질을 통제해야 했다. - 이를 위해 가능한 많은 테스트를 성공 기준으로 제공했다. - **Web Platform Tests(WPT)**를 활용해 다음을 검증했다. - 웹 표준에 대한 기능 준수 여부 - 각 브라우저 기능의 구현 상태 - AI 에이전트가 작업을 완료했는지 판단할 수 있는 명확한 기준 - WPT만으로는 실제 웹사이트에서의 동작을 충분히 검증할 수 없기 때문에 추가 테스트도 도입했다. - Chromium과 Kitesurf 양쪽에서 실제 사이트를 대상으로 Puppeteer 통합 테스트 실행 - 여러 단계의 사용자 작업과 assertion 비교 - 각 단계의 렌더링 결과를 비교하는 시각적 회귀 테스트 - 예상하지 못한 렌더링 차이를 자동으로 표시 - AI 에이전트는 기능 구현을 담당하고, 사람은 아키텍처 설계와 구현 방식 검토에 집중하는 방식이다. ## Rust와 WebAssembly 선택 - Cloudflare는 C, C++, Rust 코드를 WebAssembly로 컴파일해 Workers에서 실행할 수 있다. - Emscripten을 사용하면 많은 의존성과 모의 계층이 추가되어 결과 바이너리가 커지고 실행이 느려질 수 있다. - Kitesurf는 가능한 한 네이티브 Rust로 구현하고 `wasm-bindgen`을 통해 WebAssembly로 직접 컴파일했다. - 이를 통해 불필요한 에뮬레이션 계층을 피하고, 성능과 안정성을 높였다. ## 예외 처리와 장애 격리 - 웹페이지는 잘못된 HTML, 예상 밖의 입력, 악의적인 콘텐츠를 포함할 수 있으므로 브라우저는 일부 기능이 실패해도 세션 전체를 중단해서는 안 된다. - Kitesurf의 원칙은 다음과 같다. - 오류가 발생하면 죽은 세션 대신 빈 프레임이나 누락된 요소로 처리 - 모든 경계에서 예외를 포착 - 안전하고 비어 있는 기본값 사용 - 문제를 진단할 수 있을 만큼 충분한 로그 기록 - 목표는 페이지 일부가 손상되더라도 브라우저 요청 자체는 계속 유지하는 것이다. ## 페이지와 컴포넌트의 격리 - AI 에이전트는 작업에 따라 임의의 출처에서 코드를 실행하거나 페이지를 방문할 수 있다. - 따라서 모든 페이지 로드를 신뢰할 수 없는 입력으로 취급하고, 모든 세션을 새로 시작한다. - 각 컴포넌트는 필요한 리소스에만 접근하도록 제한한다. - Workers의 격리 모델이 기본적인 보안 경계를 제공하지만, 그것만으로 충분하지 않다. - 애플리케이션 수준에서도 컴포넌트별 접근 권한을 정의해야 한다. - 한 페이지의 데이터나 리소스가 다른 페이지로 유출되지 않도록 별도로 보장해야 한다. ## 가능한 한 무상태로 설계 - 상태가 많을수록 장애 발생 후 복구 비용이 커진다. - 무상태 컴포넌트는 다음 장점을 가진다. - 실패하면 새 인스턴스를 만들고 요청을 다시 재생하면 됨 - 필요할 때 병렬로 대량 실행 가능 - 멈춘 인스턴스를 즉시 폐기 가능 - 트래픽이 급증하는 자동화 작업에 맞춰 수요 기반으로 확장 가능 - 사용한 만큼만 비용을 지불하고 작업 종료 후 리소스를 제거 가능 - 따라서 상태가 꼭 필요하지 않은 컴포넌트는 가능한 한 무상태로 구현한다. ## 실용적인 결론 AI 브라우저는 인간용 브라우저를 그대로 축소하는 것이 아니라, 구조화된 데이터 처리·낮은 비용·높은 확장성·강한 격리를 중심으로 다시 설계해야 한다. 브라우저 자동화 서비스를 구축할 때는 표준 테스트뿐 아니라 실제 사이트 통합 테스트와 시각적 회귀 테스트를 병행하고, Rust/WebAssembly·무상태 설계·방어적인 예외 처리를 활용하는 것이 효과적이다.

cloudflare

Cloudflare가 AI를 활용해 엔지니어링 표준을 시행하는 방법 (새 탭에서 열림)

Cloudflare는 흩어져 있던 엔지니어링 지침을 통합·관리하는 표준 저장소인 **Cloudflare Codex**를 구축했다. Codex는 RFC 형식의 표준을 사람과 AI 에이전트가 작업 시점에 검색하고 적용할 수 있게 하며, 코드 리뷰·기술 설계 검토·사고 보고서 검토 등에 공통으로 활용된다. 도입 후 AI 코드 리뷰어는 약 23만 건의 위반을 발견했고, 그중 약 1만 6천 건의 병합을 차단했다. ## Codex가 필요했던 이유 - Cloudflare의 기존 지침은 공식 문서, 저장소 파일, 채팅 기록, 개인의 경험 등 여러 위치에 분산돼 있었다. - 개발자는 문제 해결보다 관련 지침을 찾는 데 많은 시간을 써야 했다. - 지침을 찾더라도 최신 정보인지, 권위 있는 기준인지, 현재 상황에 적용 가능한지 판단하기 어려웠다. - 조직이 커지면서 모든 표준을 읽고 모든 요구사항을 검토하는 것이 불가능해졌다. - 팀 이동이나 인력 변화로 조직의 지식이 유실되기 쉬웠고, 지침이 일관되게 노출·강제되지 않아 프로젝트 간 품질 편차가 발생했다. ## 도메인과 RFC 기반 거버넌스 - Codex는 아키텍처, 프런트엔드, 컨트롤 플레인, 보안, 신뢰성, TypeScript, Rust 등 여러 도메인으로 나뉜다. - 각 도메인에는 담당자가 있어 문서의 내용·일관성·품질을 관리한다. - 표준은 RFC 2119의 의미에 따라 `SHOULD`와 `MUST` 키워드를 사용한다. - `SHOULD`: 특별한 이유가 없다면 따라야 하는 권고 - `MUST`: 반드시 지켜야 하는 필수 요구사항 - RFC에는 도메인과 상태 같은 메타데이터를 담은 front matter가 포함된다. - 도메인 역량과 관심이 있는 직원은 정해진 형식의 merge request로 RFC를 제안할 수 있다. - 제안서는 점점 더 넓은 범위의 리뷰를 거치며, 도메인 담당자가 최종 승인하면 Codex에 편입되고 Astro 기반 내부 사이트에 게시된다. ## 승인과 강제를 분리한 표준 수명주기 - 승인된 RFC는 Codex 클라이언트와 에이전트가 즉시 읽고 코드·설정·문서의 위반을 탐지하는 데 사용할 수 있다. - 다만 승인 직후부터 병합을 차단하지는 않는다. - RFC가 `approved`에서 `enforced` 상태로 승격된 뒤에야 관련 요구사항이 차단 근거가 된다. - 이 단계 분리를 통해 팀이 새로운 요구사항을 받아들일 시간을 확보하고, 자동화나 예외 처리 등 강제에 필요한 준비도 마칠 수 있다. - 승인된 RFC의 위반은 일반적으로 비차단 권고로 처리되며, 강제 상태 RFC의 `MUST` 위반은 심각도에 따라 승인 보류 또는 병합 차단으로 이어진다. ## LLM을 위한 구조화와 점진적 공개 - 60개가 넘는 RFC 전체를 매번 LLM에 제공하면 컨텍스트 윈도우 부담이 커지고 결과 품질이 떨어질 수 있다. - 이를 해결하기 위해 별도의 에이전트가 RFC에서 `SHOULD`와 `MUST` 문장을 추출해 JSON 구조로 압축한다. - 각 표준 문장에는 다음 정보가 포함된다. - RFC 번호와 제목 - RFC 상태와 도메인 - 적용 수준(`SHOULD` 또는 `MUST`) - 문장이 속한 섹션 - 원문으로 연결되는 링크 - 안정적인 `slug` 식별자 - 에이전트는 우선 관련 표준 문장만 검색하고, 추가 설명이 필요할 때만 RFC 전체 내용을 불러온다. - 안정적인 slug는 RFC가 수정돼도 같은 요구사항을 추적할 수 있게 해 모니터링, 분석, 예외 처리에 활용된다. - 초기에는 간결한 Markdown을 사용했지만, 더 정확한 필터링을 위해 구조화된 JSON으로 전환했다. - 향후에는 설계·구현·런타임 등 소프트웨어 개발 생명주기 단계별 적용 범위도 메타데이터에 포함할 계획이다. ## AI 코드 리뷰 적용 - AI 코드 리뷰어는 merge request를 여러 기준으로 검사하며 Codex 준수 여부도 평가한다. - 리뷰마다 관련 RFC와 추출된 표준 문장을 검색하고, 필요한 경우에만 RFC 본문을 추가로 읽는다. - 대부분의 위반은 압축된 표준 문장만으로도 문제와 근거를 설명할 수 있다. - Codex 도입 이후 약 23만 건의 위반을 발견했다. - 이 중 약 1만 6천 건은 강제 상태 RFC의 `MUST` 요구사항 위반으로 승인 보류를 발생시켰다. ## AI 리뷰를 보완하는 빠른 린터 - AI 리뷰는 코디네이터와 여러 하위 에이전트를 실행하므로 보통 수 분이 걸린다. - 수정 후 다시 리뷰를 받아야 하는 추가 왕복과 대기 시간이 개발자 경험을 저하시킬 수 있다. - Cloudflare는 기계적으로 검증 가능한 언어별 요구사항을 별도 린터 설정 패키지로 제공하는 방식을 마련했다. - 이 린터는 Codex 표준과 정렬되며 문제를 밀리초 단위로 표시할 수 있다. - TypeScript가 첫 번째 대상 언어였고, 동시에 `oxlint`를 표준화하는 방향으로 진행됐다. ## 여러 엔지니어링 단계로의 확장 - Codex는 코드 리뷰에만 한정되지 않는다. - 기술 설계가 구현되기 전에 표준을 검토하는 spec reviewer가 이미 약 600개의 설계를 평가했다. - incident report reviewer 등 사고 분석과 운영 프로세스에도 같은 기준을 적용할 수 있다. - 하나의 관리된 표준 원천을 여러 에이전트가 공유함으로써 설계부터 구현, 운영까지 일관된 엔지니어링 기준을 적용할 수 있다. 새로운 표준은 먼저 `approved` 상태로 도입해 팀의 적응과 자동화 준비 시간을 확보한 뒤, 충분히 검증되면 `enforced`로 승격하는 방식이 실용적이다. 또한 LLM에는 전체 문서를 무작정 제공하기보다, 안정적인 식별자와 메타데이터를 갖춘 핵심 규칙을 먼저 검색하게 하고 필요할 때만 원문을 공개하는 구조가 효과적이다.

github

일찍 멈추지 마라: 메모리 속도로 소스 코드의 대소문자를 정규화하기 (새 탭에서 열림)

GitHub는 코드 검색 엔진 Blackbird에서 대규모로 수행되는 유니코드 케이스 폴딩을 메모리 대역폭에 가까운 속도로 최적화했다. 핵심은 비ASCII 문자를 만나면 즉시 중단하는 기존 최적화를 제거하고, 전체 버퍼를 분기 없이 처리해 컴파일러의 SIMD 벡터화를 유도한 것이다. Apple M4에서 단순 구현의 약 3.1GiB/s 처리량을 45GiB/s 이상으로 끌어올렸으며, 분기 없는 코드는 벡터화를 가능하게 할 때만 이점이 있다는 점도 확인했다. ## 케이스 폴딩과 소문자 변환의 차이 - 케이스 폴딩은 표시를 위한 변환이 아니라 문자열 비교를 위한 정규화다. - 대소문자만 다른 문자열을 동일하게 취급하기 위해 사용된다. - 검색 엔진 - 정규식의 `(?i)` 옵션 - 대소문자를 구분하지 않는 사용자명과 호스트명 - 일반적인 소문자 변환과 달리 케이스 폴딩은: - 로케일에 독립적이다. - 문맥에 의존하지 않는다. - 비교 관계가 일관되고 대칭적이다. - 그리스어 final sigma, 터키어의 `I`, 독일어 `ß`처럼 소문자 변환과 케이스 폴딩 결과가 달라지는 문자가 있어 `to_lowercase`를 대체 수단으로 사용하면 잘못된 검색 결과가 발생할 수 있다. - 공개된 Rust `casefold` 크레이트는 Unicode `CaseFolding.txt`의 단일 문자 변환인 C·S 상태만 구현한다. - `ß → ss`와 같은 다중 문자 변환은 지원하지 않는다. - 터키어 전용 폴딩도 지원하지 않는다. - ripgrep과 정규식 엔진도 유사한 제한을 둔다. ## GitHub에서 케이스 폴딩이 중요한 이유 - Blackbird는 1억 8천만 개 이상의 저장소와 480TB가 넘는 소스 코드를 색인한다. - 색인 전에 모든 바이트를 폴딩하고, 검색 결과 후보를 확인할 때도 케이스 폴딩이 반복적으로 수행된다. - 소스 코드는 대부분 ASCII이므로 ASCII 경로를 메모리 속도로 처리하는 것이 가장 큰 성능 개선 요소다. - 비ASCII 입력은 드물기 때문에, 최적화의 목표는: - 흔한 ASCII 경로를 최대한 빠르게 만들고 - 드문 유니코드 경로가 ASCII 성능을 방해하지 않게 하는 것이다. ## 조기 종료를 제거한 ASCII 처리 기존 방식은 비ASCII 바이트를 만나면 즉시 반복문을 종료하고 유니코드 처리로 넘겼다. ```text if byte >= 0x80 { break } ``` 하지만 이 데이터 의존적 `break`는 컴파일러의 루프 벡터화를 막는다. 개선된 구현은 다음과 같이 동작한다. - 모든 바이트를 끝까지 순회한다. - `high_bit_acc |= byte`로 모든 바이트의 최상위 비트를 누적한다. - 반복문이 끝난 뒤 누적값을 한 번만 검사해 비ASCII 문자가 있었는지 확인한다. - 따라서 반복문 내부에는 데이터에 따른 분기나 조기 종료가 없다. 이 방식은 비ASCII 여부를 동일하게 알아내면서도 SIMD 명령을 사용할 수 있게 한다. ## 분기 없는 ASCII 대소문자 변환 ASCII 대문자 변환도 조건문 대신 산술 연산으로 처리한다. - `b.wrapping_sub(b'A') < 26` - 바이트가 `A`부터 `Z` 사이일 때만 참이 된다. - 별도의 분기 없이 대문자 여부를 0 또는 1 마스크로 만든다. - `u8::from(is_upper) << 5` - 대문자이면 ASCII의 비트 5를 설정해 소문자로 바꾼다. - 그 외 문자는 아무 변화가 없다. - 모든 바이트를 항상 저장하므로 조건부 저장 명령도 제거된다. 결과적으로 루프는 다음 특성을 갖는다. - 데이터 의존적 분기 없음 - 조기 종료 없음 - 연속적인 메모리 접근 - LLVM이 NEON 기반 16바이트 단위 SIMD 코드 생성 가능 ## 벤치마크와 성능 개선 Apple M4에서 5.7KB ASCII 버퍼를 처리한 누적 측정 결과는 다음과 같다. - 조기 종료와 분기 조건을 사용하는 순진한 구현: **3.1GiB/s** - 본문만 분기 없이 바꾸고 조기 종료를 유지한 구현: **2.6GiB/s** - 조기 종료를 제거한 구현: **7.6GiB/s** - 대문자 판별과 저장까지 분기 없이 처리한 최종 구현: **45GiB/s 이상** 성능 향상의 핵심은 단순히 분기를 없앤 것이 아니다. - 조기 종료 제거가 루프 벡터화를 가능하게 했다. - 대문자 변환의 분기 제거가 완전한 벡터화를 가능하게 했다. - 최종 성능은 사실상 메모리 대역폭 한계에 도달했다. ## 스칼라 코드에서는 분기 없는 방식이 느릴 수 있다 - 조기 종료를 유지한 채 본문만 분기 없이 바꾼 구현은 오히려 3.1GiB/s에서 2.6GiB/s로 느려졌다. - 기존 분기 방식은 실제로 값이 바뀌는 대문자일 때만 저장한다. - 소문자, 숫자, 공백이 대부분인 일반 텍스트에서는 조건부 저장 분기가 매우 잘 예측된다. - 반면 분기 없는 구현은 모든 바이트를 무조건 저장해 불필요한 쓰기 트래픽이 발생한다. - 따라서 분기 없는 코드는 그 자체로 항상 빠른 것이 아니다. - 이 사례에서는 분기 없는 코드가 SIMD 벡터화를 가능하게 하는 수단이었기 때문에 최종적으로 큰 이득을 냈다. 실용적으로는 데이터 규모가 크고 반복 횟수가 많은 바이트 처리에서 조기 종료가 정말 최적인지 확인해야 한다. 특히 루프의 조기 종료가 SIMD 벡터화를 막는다면, 전체 버퍼를 일정한 흐름으로 처리하고 마지막에 상태를 확인하는 방식이 훨씬 빠를 수 있다.

aws

AWS Graviton5 프로세서 기반 Amazon EC2 C9g 및 C9gd 인스턴스 출시 | Amazon Web Services (새 탭에서 열림)

AWS가 AWS Graviton5 기반의 컴퓨팅 최적화 EC2 C9g 및 로컬 NVMe 스토리지를 갖춘 C9gd 인스턴스를 정식 출시했다. C9g는 이전 C8g보다 vCPU당 최대 25% 높은 성능과 더 빠른 메모리·대형 캐시·향상된 네트워크 성능을 제공하며, C9gd는 여기에 고속 로컬 SSD를 추가한다. 두 인스턴스는 배치 처리, HPC, 동영상 인코딩, 실시간 분석, CPU 기반 ML 추론, 에이전틱 AI 등에 적합하다. ## Graviton5 기반 성능 향상 - C9g는 이전 세대 C8g 대비 vCPU당 최대 25% 높은 성능을 제공한다. - DDR5 8800MT/s 메모리를 사용해 클라우드 프로세서 인스턴스 중 가장 빠른 메모리 성능을 제공한다. - L3 캐시가 5배 늘어나 데이터 대기 시간을 줄이고, 인메모리 분석과 실시간 애플리케이션의 처리량을 높인다. - Graviton4 기반 인스턴스 대비 패킷 처리 성능이 최대 3배 향상됐다. - 평균적으로 이전 세대보다 네트워크 대역폭은 최대 15%, EBS 대역폭은 최대 20% 높다. - 48xlarge는 네트워크 최대 100Gbps, EBS 최대 72Gbps를 지원하며, 이는 이전 세대 대비 최대 2배 수준이다. ## C9g와 C9gd의 용도 차이 - **C9g** - Amazon EBS를 스토리지로 사용하는 배치 작업, 동영상 인코딩, 분산 분석에 적합하다. - 높은 코어 수와 대형 캐시가 필요한 에이전틱 AI의 병렬 실행 환경과 CPU 중심 추론에 유리하다. - 실시간 분석, 게임, 과학 모델링, 광고 서버 등 CPU 집약적 워크로드에 활용할 수 있다. - **C9gd** - C9g의 컴퓨팅 성능에 로컬 NVMe SSD를 결합한 유형이다. - HPC 시뮬레이션의 임시 작업 공간, ML 추론 캐시, 광고 서버의 로컬 버퍼 등에 적합하다. - 로컬 스토리지 성능은 이전 세대 대비 최대 30% 향상됐다. ## 세부 네트워크·스토리지 기능 - 중간형부터 48xlarge까지 11개 크기와 베어메탈 옵션을 제공한다. - **Instance Bandwidth Configuration(IBC)**으로 EBS와 VPC 네트워크 간 대역폭 배분을 최대 25% 조정할 수 있다. - 데이터베이스나 캐시처럼 특정 대역폭 구성이 중요한 워크로드를 세밀하게 최적화할 수 있다. - ENA Express를 지원해 향상된 네트워킹을 제공한다. - 가상 인스턴스에는 최대 128개의 EBS 볼륨을 연결할 수 있다. - NVMe 인스턴스 스토어 사용 시 I/O 크기별 지연 시간 히스토그램과 1초 단위의 고해상도 성능 지표를 CloudWatch 또는 `nvme-cli`에서 추가 비용 없이 확인할 수 있다. ## Nitro Isolation Engine 적용 - C9g와 C9gd는 Nitro Isolation Engine을 탑재한 최초의 컴퓨팅 최적화 EC2 인스턴스다. - 이 기능은 AWS Nitro System의 구성 요소로, Rust로 구현된 Nitro Hypervisor 기반 격리 기능이다. - 가상 머신 간 메모리, CPU 레지스터 상태, I/O 장치 접근을 최소한의 API를 통해 중재해 격리를 강화한다. - 공식 검증 결과와 적용 범위는 AWS 기술 백서에서 확인할 수 있다. ## 제공 방식과 리전 - On-Demand, Spot, Dedicated Instance, Dedicated Host 및 Savings Plans를 지원한다. - 현재 미국 동부 오하이오·버지니아 북부, 미국 서부 오리건, 유럽 프랑크푸르트 리전에서 사용할 수 있다. - AWS Management Console, AWS CLI, AWS SDK로 생성할 수 있으며 추가 리전은 추후 제공될 예정이다. 워크로드가 CPU 처리량과 메모리 접근 속도를 중시한다면 C9g를, 고성능 로컬 임시 스토리지까지 필요하다면 C9gd를 우선 검토하는 것이 좋다. 실제 도입 전에는 애플리케이션을 Graviton5에서 벤치마크하고, IBC를 활용해 네트워크와 EBS 대역폭 구성을 조정하는 것이 권장된다.

gitlab

Git 2.55.0의 새로운 기능은 무엇인가? (새 탭에서 열림)

Git 2.55.0은 커밋 수정, 대규모 저장소 성능, 여러 원격 저장소 관리, 로그 가독성을 개선한 릴리스입니다. 특히 `git history fixup`, Linux용 내장 fsmonitor, 원격 그룹 대상 `git push`, `git log --graph`의 레인 폭 제한이 눈에 띕니다. 또한 Git 코드베이스의 Rust 도입과 부분 클론에서의 `git grep`, `git cherry` 성능 개선도 주요 변경 사항으로 소개됩니다. ## `git history fixup`으로 기존 커밋 수정 - 기존 방식은 다음 두 단계가 필요했습니다. ```bash git commit --fixup=<commit-id> git rebase -i --autosquash <commit-id>^ ``` - Git 2.55에서는 스테이징된 변경 사항을 지정한 커밋에 바로 반영할 수 있습니다. ```bash git history fixup <commit-id> ``` - 대화형 리베이스 없이 커밋을 수정할 수 있어 절차가 간단해집니다. - 수정된 커밋을 포함하는 다른 로컬 브랜치도 함께 갱신됩니다. - 따라서 스택형 브랜치에서 중간 커밋을 수정하면 관련 브랜치가 자동으로 재배치됩니다. ## Linux용 내장 fsmonitor 데몬 - 대규모 모노레포에서는 `git status`가 전체 작업 트리를 탐색해야 하므로 느려질 수 있습니다. - `core.fsmonitor`를 활성화하면 파일 시스템 변경을 백그라운드에서 감시하고, Git이 변경 가능성이 있는 파일만 확인할 수 있습니다. - 기존 내장 fsmonitor는 Windows와 macOS만 지원했지만 Git 2.55부터 GNU/Linux도 지원합니다. - Linux에서는 권한 상승이 필요한 `fanotify` 대신 `inotify`를 사용합니다. - 저장소의 모든 디렉터리에 감시자를 등록하므로, 큰 저장소에서는 감시자 수 제한을 초과할 수 있습니다. - 필요하면 다음 커널 설정을 늘려야 합니다. ```text fs.inotify.max_user_watches ``` ## 원격 그룹으로 한 번에 push - 기존에는 원격 그룹을 `git fetch`에서만 사용할 수 있었습니다. - 다음과 같이 원격 그룹을 설정합니다. ```bash git config set remotes.forks "origin upstream" ``` - Git 2.55부터 그룹 전체에 브랜치를 push할 수 있습니다. ```bash git push forks main ``` - 지정한 브랜치가 그룹에 포함된 각 원격 저장소로 독립적으로 전송됩니다. - 각 원격 저장소의 `remote.<name>.push` 매핑과 mirror 설정도 개별적으로 적용됩니다. ## `git log --graph`의 레인 폭 제한 - `git log --graph`는 브랜치와 병합 관계를 ASCII 그래프로 표시합니다. - 기여자가 많거나 병렬 브랜치가 많은 저장소에서는 그래프가 지나치게 넓어져 가독성이 떨어질 수 있습니다. - Git 2.55는 그래프의 레인 폭을 제한하는 기능을 제공해 복잡한 커밋 이력을 보다 compact하게 표시할 수 있도록 합니다. ## Rust 도입과 부분 클론 성능 개선 - Git 2.55 릴리스의 추가 주제로 Git 코드베이스 내 Rust 사용 확대가 소개됩니다. - 부분 클론 환경에서 `git grep`과 `git cherry`가 더 빠르게 동작하도록 성능 개선이 이루어졌습니다. - 제공된 글 내용에는 Rust 도입 방식이나 각 명령의 구체적인 개선 수치는 자세히 설명되지 않습니다. 대규모 저장소를 사용한다면 Linux에서 `core.fsmonitor=true`를 활성화하고, `inotify` 감시자 제한을 점검하는 것이 좋습니다. 여러 미러나 포크에 동시에 배포하는 팀은 원격 그룹 push를 활용하면 반복 작업을 줄일 수 있습니다.

cloudflare

hyper HTTP 라이브러리에서 버그를 발견한 방법 (새 탭에서 열림)

Cloudflare의 Images binding을 로컬 Unix 소켓 기반 구조로 개편한 뒤, 대용량 이미지 응답이 간헐적으로 잘리는 버그가 발생했다. 응답은 HTTP 200과 정상적인 `Content-Length`를 반환했지만 실제 본문은 수백 KB만 전달되어 이미지가 부분적으로 렌더링되거나 디코딩에 실패했다. 원인은 특정 조건에서 발생하는 hyper 라이브러리의 레이스 컨디션이었으며, 최종적으로 네 줄의 코드 수정으로 해결됐다. ### Images binding과 hyper의 데이터 흐름 - Workers는 바인딩을 통해 Images 서비스에 이미지 데이터를 직접 전달하고, 변환 결과를 스트림으로 받을 수 있다. - 이미지 변환 과정은 다음과 같이 진행된다. - Workers 런타임이 소켓을 통해 Images 서비스에 요청을 보낸다. - Images 서비스가 이미지를 합성·리사이즈·트랜스코딩한다. - 변환된 전체 이미지를 메모리 블록으로 hyper에 전달한다. - hyper가 데이터를 내부 버퍼에 저장한 뒤 소켓의 송신 버퍼로 기록한다. - 소켓의 양 끝에는 커널이 관리하는 버퍼가 있다. - 수신자가 충분히 빠르면 hyper가 한 번에 모든 데이터를 보내고 소켓을 종료할 수 있다. - 수신자가 조금이라도 느리면 송신 버퍼가 가득 차고, hyper는 공간이 생길 때까지 추가 쓰기를 기다려야 한다. ### 네트워크 중계에서 로컬 Unix 소켓으로 전환 - 초기 Images binding은 Workers 런타임과 Images 사이에서 FL이라는 내부 중계 서비스를 거쳤다. - FL은 DNS 조회와 라우팅 등 전체 네트워크 처리 파이프라인을 수행했기 때문에 오버헤드가 있었다. - 2025년 12월, Cloudflare는 FL을 같은 머신에서 실행되는 내부 Worker binding으로 교체했다. - 새 구조는 네트워크 소켓 대신 Unix 소켓으로 서비스를 직접 연결했다. - 이 변경으로 다음 효과를 기대했다. - 네트워크 스택과 FL 처리 과정 제거 - Images 요청 경로 단축 - Images 팀이 독립적으로 binding을 배포하고 변경 가능 - 그러나 출시 며칠 뒤부터 대용량 이미지 응답 실패 제보가 접수됐다. ### HTTP 200이지만 잘린 응답 - 고객 사례는 두 단계의 이미지 처리 파이프라인을 중첩한 비표준 구성이었다. - 내부 파이프라인: R2의 JPEG와 PNG를 합성해 JPEG 생성 - 외부 파이프라인: 결과 이미지를 다시 압축·변환·리사이즈 - 실제 문제는 내부 transformation binding의 반환 경로에서 발생했다. - 외부 파이프라인은 내부 응답에서 다음과 같은 모순을 받았다. - 상태 코드는 `200 OK` - `Content-Length`는 수 MB로 설정 - 실제 수신 본문은 일부 데이터에 불과함 - 한 사례에서는 예상 크기 3.3MB 중 약 200KB만 전달됐다. - 상위 계층에서는 다음 오류가 발생했지만, 실제 원인이 어느 서비스에 있는지는 즉시 알기 어려웠다. ```text error reading a body from connection: end of file before message length reached ``` - 브라우저에서는 이미지 형식에 따라 일부만 표시되거나, 하단이 회색으로 남거나, 아예 깨진 이미지로 표시됐다. ### 재현과 원인 범위 좁히기 - 개발팀은 고객의 중첩 파이프라인을 재현하는 Worker를 만들었다. - 이후 외부 파이프라인과 여러 계층을 하나씩 제거해 binding 단독으로도 문제를 재현할 수 있음을 확인했다. - 배치 요청을 보내는 간단한 스크립트로 재현을 자동화했다. - 초기 실행에서는 25건 중 19건이 실패했다. - 매번 도착한 데이터가 약 200KB였는데, 이는 운영 환경의 소켓 버퍼 크기와 매우 유사했다. - 이를 통해 문제는 고객 설정이 아니라 소켓 버퍼가 가득 찬 뒤 hyper가 응답 전송과 연결 종료를 처리하는 방식과 관련 있음을 추정할 수 있었다. - 최종 원인은 특정 타이밍에서 발생하는 hyper 내부의 레이스 컨디션으로 밝혀졌고, 수정에는 네 줄의 코드만 필요했다. ### 실용적인 결론 소켓 기반 스트리밍에서는 `200 OK`나 올바른 `Content-Length`만으로 전송 성공을 판단할 수 없다. 특히 송신 버퍼가 가득 차는 상황, 느린 수신자, 데이터 기록과 연결 종료가 동시에 일어나는 경로를 반드시 테스트해야 하며, 대용량·중첩 파이프라인을 포함한 재현 테스트가 간헐적인 네트워크 버그를 찾는 데 결정적이다.

github

언어 서버로 GitHub Copilot CLI에 진정한 코드 인텔리전스를 더하세요 (새 탭에서 열림)

GitHub Copilot CLI는 LSP(Language Server Protocol)를 연동하면 단순한 텍스트 검색이나 바이트코드 추출을 넘어, 코드의 타입·정의·참조를 의미론적으로 이해할 수 있다. 글에서는 이를 자동화하는 **LSP Setup 스킬**의 동작 방식과 설정 형식, 지원 언어 및 설치 절차를 소개하며, 결과적으로 더 정확하고 빠른 코드 분석이 가능해진다고 설명한다. ## 텍스트 검색 기반 코드 이해의 한계 - LSP가 없으면 Copilot CLI는 의존성 정보를 찾기 위해 다음과 같은 우회 작업을 수행한다. - Java JAR 파일 검색 및 임시 디렉터리 추출 - `.class` 파일에 대한 `grep` - Python의 `site-packages`나 TypeScript의 `node_modules` 파일 직접 탐색 - 이런 방식은 단순한 패턴 검색에 의존하므로 다음 정보를 정확히 처리하기 어렵다. - 제네릭 타입 - 메서드 오버로드 - 전이 의존성의 타입 - 컴파일된 바이트코드 내부의 의미 구조 - 반면 LSP의 `textDocument/definition` 요청은 심볼의 정확한 소스 위치, 해석된 타입, 메서드 시그니처를 반환한다. ## LSP Setup 스킬의 7단계 동작 ### 1. 언어 선택 - `ask_user`를 사용해 사용자가 LSP를 설정할 프로그래밍 언어를 선택한다. - 선택한 언어가 이후 설치 명령과 설정 생성을 결정한다. ### 2. 운영체제 확인 - macOS와 Linux에서는 `uname -s`를 사용한다. - Windows에서는 `$env:OS` 또는 `%OS%`를 확인한다. - 운영체제에 따라 LSP 서버 설치 방법을 다르게 적용한다. - macOS Java: `brew install jdtls` - Linux Java: Eclipse 등에서 다운로드 ### 3. LSP 서버 조회 - `references/lsp-servers.md`에 14개 언어의 정보가 미리 정리되어 있다. - 각 언어별로 다음 내용을 제공한다. - 운영체제별 설치 명령 - 실행 파일 이름 - 바로 사용할 수 있는 설정 예시 ### 4. 설정 범위 선택 - 사용자 전역 설정: - `~/.copilot/lsp-config.json` - 모든 저장소에 적용 - 저장소별 설정: - 저장소 루트의 `lsp.json` - 또는 `.github/lsp.json` - 특정 프로젝트에만 적용 - 두 설정이 모두 존재하면 저장소별 설정이 우선한다. ### 5. LSP 서버 설치 - 언어에 맞는 설치 명령을 자동으로 실행한다. - 예시는 다음과 같다. ```bash npm install -g typescript typescript-language-server brew install jdtls rustup component add rust-analyzer ``` ### 6. 설정 파일 생성 및 병합 - 설정은 `lspServers` 객체 아래에 서버별 항목을 둔다. ```json { "lspServers": { "java": { "command": "jdtls", "args": [], "fileExtensions": { ".java": "java" } } } } ``` - 주요 규칙은 다음과 같다. - `command`는 `$PATH`에 있거나 절대 경로여야 한다. - 일반적으로 표준 입출력 통신을 위해 `--stdio`를 `args`에 지정한다. - `fileExtensions`는 점으로 시작하는 확장자와 VS Code 언어 식별자를 연결한다. - 기존 설정은 삭제하지 않고 새로운 항목을 병합한다. - `jdtls`처럼 표준 입출력을 내부적으로 처리하는 서버는 별도 인자가 필요하지 않을 수 있다. ### 7. 설치 및 설정 검증 - `which <binary>` 또는 Windows의 `where.exe`로 실행 파일이 접근 가능한지 확인한다. - 설정 파일이 올바른 JSON인지 검증한다. ## 지원 언어와 확장 방식 - 스킬은 현재 14개 언어에 대한 사전 정의 서버 정보를 제공한다. - 미리 매핑되지 않은 언어를 만나면 적절한 LSP 서버를 검색하고 수동 설정 과정을 안내한다. - 따라서 지원 목록에 없는 언어도 서버만 확보하면 직접 추가할 수 있다. ## 설정 후 가능한 코드 인텔리전스 LSP 연동 후 Copilot CLI는 다음 작업을 수행할 수 있다. - 의존성 전체에서 타입을 정확히 해석 - 저장소에 소스 코드가 없는 외부 라이브러리의 정의로 이동 - 프로젝트 전반에서 심볼의 모든 참조 검색 - 함수·클래스·타입의 hover 문서 확인 - 메서드 시그니처와 타입 관계를 기반으로 코드 수정 및 분석 그 결과 불필요한 JAR 압축 해제나 `node_modules` 검색이 줄고, 잘못 해석한 API에 기반한 코드 생성도 감소한다. ## 설치 및 사용 절차 1. Awesome Copilot의 LSP Setup 스킬 페이지에서 ZIP 파일을 다운로드한다. 2. 다음 명령으로 `~/.copilot/skills/`에 압축을 푼다. ```bash unzip lsp-setup.zip -d ~/.copilot/skills/ ``` 3. 실행 중인 Copilot CLI를 `/exit`로 종료한 뒤 다시 실행한다. 4. “set up LSP for Java” 또는 “enable code intelligence for Python”처럼 요청한다. 5. 설정이 끝나면 Copilot CLI를 다시 시작한다. 6. `/lsp`로 서버 상태를 확인하고, 의존성 심볼의 정의 이동을 테스트한다. 프로젝트 규모가 크거나 외부 라이브러리 사용이 많은 경우에는 LSP Setup 스킬을 적용하는 것이 좋다. 특히 Java, TypeScript, Python처럼 타입과 의존성 관계가 복잡한 언어에서는 텍스트 검색보다 정확한 코드 분석과 안정적인 결과를 기대할 수 있다.

cloudflare

프로젝트 글래스윙: Mythos가 우리에게 보여준 것 (새 탭에서 열림)

Mythos Preview는 단순히 취약점을 찾아내는 수준을 넘어, 여러 취약점을 연결해 실제 공격 경로를 구성하고 실행 가능한 증명 코드까지 생성하는 새로운 단계의 보안 도구로 평가된다. 그러나 모델의 자발적 거부는 일관되지 않으며, 탐색적 모델의 높은 오탐률 때문에 대규모 운영에는 별도의 안전장치와 검증·분류 체계가 필요하다. Project Glasswing의 핵심 교훈은 강력한 모델 자체뿐 아니라 이를 통제하고 결과를 검증하는 아키텍처가 함께 발전해야 한다는 점이다. ## Mythos Preview가 달라진 점 - Cloudflare는 Project Glasswing의 일환으로 Mythos Preview를 50개가 넘는 자체 저장소에 적용했다. - 이전 범용 프런티어 모델과의 단순한 성능 비교보다, Mythos가 실제로 수행하는 작업의 성격을 이해하는 것이 중요하다고 설명한다. - 기존 모델도 개별 버그를 발견하거나 영향도를 분석할 수 있었지만, 여러 조각을 하나의 공격으로 연결하는 단계에서 자주 멈췄다. ## 여러 취약점을 연결하는 공격 체인 - 실제 공격은 하나의 버그가 아니라 여러 취약점과 공격 원시 기능을 조합해 완성되는 경우가 많다. - 예를 들어: - use-after-free를 임의 메모리 읽기·쓰기 기능으로 전환 - 제어 흐름 탈취 - ROP(Return-Oriented Programming) 체인 구성 - 최종적으로 시스템 제어권 획득 - Mythos Preview는 낮은 심각도로 분류될 만한 개별 버그들을 결합해 더 심각한 실제 공격 경로를 추론할 수 있었다. - 이러한 추론 과정이 자동화된 스캐너보다는 숙련된 보안 연구자의 작업에 가깝게 나타났다는 점이 두드러졌다. ## 반복 실행을 통한 익스플로잇 증명 - Mythos Preview는 의심되는 취약점을 설명하는 데 그치지 않고, 이를 재현하는 코드를 직접 작성한다. - 생성한 코드를 격리된 scratch 환경에서 컴파일하고 실행해 예상한 동작이 발생하는지 확인한다. - 실패하면 오류 결과를 분석하고 가설을 수정한 뒤 다시 시도한다. - 이 반복 루프를 통해 단순한 “취약할 가능성”과 실제 악용 가능한 취약점을 구분한다. - 따라서 취약점 탐지와 익스플로잇 가능성 입증 사이의 간극을 모델 스스로 줄일 수 있다. ## 정당한 보안 연구에서의 모델 거부 - Project Glasswing에서 제공된 Mythos Preview에는 일반 공개 모델에 적용되는 추가 안전장치가 없었지만, 모델 자체적으로 일부 요청을 거부하는 경향이 나타났다. - 그러나 거부 기준은 일관되지 않았다. - 동일한 코드라도 실행 환경의 사소한 변화에 따라 연구를 허용하거나 거부했다. - 심각한 메모리 버그를 확인한 뒤에도 시연용 익스플로잇 작성은 거부할 수 있었다. - 요청 표현을 바꾸거나 실행 시점을 달리하면 반대 결과가 나오기도 했다. - 이러한 자발적 안전장치는 실제로 존재하지만, 확률적이고 상황 의존적이므로 단독 안전 경계로 사용할 수 없다. - 향후 공개되는 강력한 사이버 보안 모델에는 통제된 연구 환경 밖에서도 사용할 수 있도록 별도의 안전장치가 필요하다. ## 신호 대 잡음 문제와 오탐 - 보안 취약점 분석에서 가장 어려운 일 중 하나는 발견된 문제가 실제인지, 악용 가능한지, 즉시 수정해야 하는지를 판별하는 것이다. - AI 스캐너와 AI가 생성한 코드의 확산은 이 문제를 더욱 악화시켰으며, Cloudflare는 여러 후속 검증 단계를 구축해 대응하고 있다. ### 프로그래밍 언어의 영향 - C와 C++는 메모리를 직접 제어할 수 있어 다음과 같은 취약점이 발생하기 쉽다. - 버퍼 오버플로 - 경계 밖 읽기·쓰기 - 메모리 수명 관리 오류 - Rust와 같은 메모리 안전 언어는 이러한 버그 유형의 상당수를 컴파일 시점에 제거한다. - 실험에서는 메모리 비안전 언어로 작성된 프로젝트에서 오탐이 일관되게 더 많이 발생했다. ### 모델의 탐색 편향 - 숙련된 사람은 발견 내용과 함께 확신 수준을 명확히 제시하지만, 모델은 코드에 문제가 없어도 문제를 찾으려는 경향이 있다. - 결과에는 “가능성이 있다”, “잠재적으로”, “이론상 가능하다”와 같은 추측성 표현이 많이 포함된다. - 탐색 단계에서는 이런 보수적·과잉 탐지 성향이 유용할 수 있다. - 하지만 실제 트리아지 큐에서는 각각의 추측성 결과를 사람이 검증하고 기각해야 하므로, 수천 건으로 확장될 경우 인력과 모델 토큰 비용이 크게 누적된다. ## 실용적인 결론 Mythos Preview 같은 모델은 취약점 후보 발굴을 넘어 공격 체인 구성과 재현 증명까지 수행할 수 있어 보안 연구의 생산성을 크게 높일 수 있다. 다만 결과를 그대로 신뢰해서는 안 되며, 격리된 실행 환경, 다단계 검증, 신뢰도 기반 우선순위화, 일관된 안전 정책을 함께 구축해야 대규모 운영에 적합하다.

gitlab

Codex와 GitLab으로 버그 수정 (새 탭에서 열림)

Codex는 터미널에서 코드를 분석하고 수정·테스트하는 데 강력하지만, 실제 배포에는 이슈 관리, 머지 리퀘스트, CI/CD, 코드 리뷰와 승인 과정이 필요하다. 글은 GitLab과 Codex를 연계해 Rust WebSocket 버그를 수정하고, GitLab MCP로 이슈와 개발 맥락을 반영하며, GitLab Duo Agent Platform의 외부 에이전트로 리뷰 피드백까지 처리하는 흐름을 소개한다. 핵심 결론은 코딩 에이전트의 빠른 구현 능력과 GitLab의 소프트웨어 생명주기 관리 기능을 결합해야 코드 작성부터 운영 배포까지 연결할 수 있다는 것이다. ## Codex와 GitLab을 결합하는 전체 워크플로 - Codex는 저장소 안에서 코드를 읽고, 수정안을 만들고, 명령을 실행하고, 테스트까지 수행한다. - 그러나 코드 작성만으로는 소프트웨어가 배포되지 않는다. - GitLab 이슈 - 머지 리퀘스트 - CI/CD 파이프라인 - 보안 스캔 - 코드 리뷰 - 최종 사람의 승인 등이 필요하다. - 글에서는 Tanuki IoT Platform 프로젝트의 Rust metrics backend를 대상으로 세 가지 활용 사례를 제시한다. - 로컬 Codex로 Rust WebSocket 버그 수정 - GitLab MCP로 이슈 요구사항과 개발 맥락을 Codex에 제공 - GitLab Duo Agent Platform에서 Codex를 외부 에이전트로 사용해 MR 리뷰 피드백 처리 ## 실습 환경과 프로젝트 구조 - 필요한 환경: - 터미널에서 실행 가능한 Codex - 이슈가 포함된 GitLab 프로젝트 - 선택적으로 GitLab MCP 서버와 GitLab Duo Agent Platform - Rust 컴파일러와 Cargo - 프로젝트를 GitLab에 가져온 뒤 로컬에 clone하고 저장소 루트에서 `codex`를 실행한다. - 주요 대상은 `backend/` 아래의 Rust metrics store다. - 센서는 REST API로 측정값을 전송한다. - 대시보드는 WebSocket 스트림으로 실시간 데이터를 받는다. - `AGENTS.md`를 통해 Codex에 Rust 도구 체인, 빌드 명령, 테스트 방법, 코드 품질 기준을 알려줄 수 있다. ## WebSocket 메트릭 필터 버그 재현 - 백엔드는 REST API에서는 메트릭 필터링을 지원하지만, WebSocket 스트림에서는 필터가 제대로 적용되지 않는 문제가 있었다. - 서버 실행: ```bash PORT=9090 cargo run --manifest-path backend/rust-metrics-store/Cargo.toml ``` - 특정 센서와 메트릭을 구독: ```bash websocat 'ws://localhost:9090/ws?sensor=arduino-iot-collector&metric=temperature_celsius' ``` - 같은 센서에 서로 다른 메트릭을 전송한다. ```bash curl -s -X POST http://localhost:9090/api/metrics \ -H 'Content-Type: application/json' \ -d '{"sensor":"arduino-iot-collector","metric":"temperature_celsius","value":23.5}' curl -s -X POST http://localhost:9090/api/metrics \ -H 'Content-Type: application/json' \ -d '{"sensor":"arduino-iot-collector","metric":"humidity_percent","value":61.2}' ``` - 기대 결과는 `temperature_celsius`만 수신하는 것이다. - 실제로는 `humidity_percent`도 스트림에 나타나므로, `/ws`가 `metric` 쿼리 파라미터를 무시하고 있음을 확인할 수 있다. ## 로컬 Codex를 이용한 버그 수정 - Codex에 다음과 같이 작업을 요청한다. ```text I need help with a backend change to add metric filtering to /ws so live streams can be narrowed to one metric. ``` - Codex는 저장소와 `AGENTS.md`를 분석해 다음 작업을 수행한다. - `/ws` 핸들러의 기존 sensor 필터 로직 조사 - 선택적 `metric` 쿼리 파라미터 지원 추가 - 센서와 메트릭 조합에 따른 필터링 구현 - 관련 테스트 추가 - `README.md`와 `AGENTS.md` 등 문서 갱신 - 변경 후 포맷팅, 테스트, 빌드를 실행하고 최종 diff를 검토한다. - 이후 Codex에 브랜치 생성, 커밋, 원격 저장소 push를 맡길 수 있다. ## GitLab 머지 리퀘스트와 CI/CD 검증 - 코드가 MR에 올라가면 GitLab이 이후 생명주기를 담당한다. - 파이프라인에서 다음 검증이 수행된다. - 빌드와 테스트 - 보안 스캔 - Rust 코드 스타일 및 품질 검사 - GitLab Duo Code Review - 배포 후에는 동일한 로컬 테스트를 다시 실행해 sensor와 metric을 모두 지정했을 때 요청한 메트릭만 전달되는지 확인한다. - 검증 결과와 로컬 테스트 내용을 MR에 댓글로 남겨 리뷰 맥락을 공유한다. ## GitLab MCP로 이슈와 요구사항 연결 - 로컬 저장소만 보는 Codex는 GitLab에 있는 다음 정보를 알 수 없다. - 버그 이슈의 상세 내용 - 합의된 기능·비기능 요구사항 - 구현 메모 - 관련 MR 상태 - 파이프라인 상태 - GitLab MCP 서버를 연결하면 Codex가 이슈를 직접 조회할 수 있다. - 이슈에는 다음과 같은 내용이 포함될 수 있다. - 문제 재현 방법 - 기능 요구사항 - 비기능 요구사항 - 필요한 테스트 - `README.md`, `AGENTS.md` 갱신 요구 - 구현 방향에 대한 메모 - 따라서 사용자가 긴 요구사항을 프롬프트에 복사하지 않아도, Codex가 GitLab 이슈를 단일 기준 정보로 활용해 구현할 수 있다. - 이는 단순히 코드를 고치는 것보다 프로젝트의 합의된 요구사항과 개발 프로세스에 맞춘 변경을 가능하게 한다. ## 실용적인 적용 권장 사항 - Codex에는 작업 범위와 기대 동작을 명확히 요청하고, `AGENTS.md`에 빌드·테스트·스타일 규칙을 기록하는 것이 좋다. - 코드 수정 전에는 실제 API와 WebSocket 동작을 명령줄에서 재현해 버그를 객관적으로 확인한다. - GitLab MCP를 사용해 이슈를 직접 참조하게 하면 요구사항 누락을 줄일 수 있다. - Codex가 작성한 코드는 GitLab MR, CI/CD, 보안 스캔, 사람의 리뷰를 거친 뒤 배포해야 한다.

discord

Discord가 대규모로 ScyllaDB 클러스터를 자동화하는 방법 (새 탭에서 열림)

Discord는 수백 개의 ScyllaDB 노드를 소수의 인원이 운영하기 위해, 취약한 스크립트 모음 대신 Scylla Control Plane(SCP)을 구축했다. SCP는 실제 트래픽을 복제하는 shadow cluster를 자동으로 생성·검증해 ScyllaDB 업그레이드와 인프라 변경을 운영 환경에 적용하기 전에 안전하게 테스트한다. 작업을 태스크와 워크플로로 구조화하고, 사전 조건·재시도·상태 저장·병렬성 제어를 제공함으로써 클러스터 구축 시간을 크게 줄이고 실패 시 처음부터 다시 시작해야 하는 문제를 해결하는 것이 핵심이다. ## 대규모 ScyllaDB 운영의 어려움 - Discord의 Persistence Infrastructure 팀은 7명으로 Elasticsearch, Postgres, ScyllaDB 클러스터를 운영한다. - ScyllaDB는 메시지, 채널, 서버, 사용자 데이터 대부분을 저장하며, 수십 개 클러스터와 수백 개 노드로 구성된다. - 주요 운영 작업에는 다음이 포함된다. - 설정 변경 후 롤링 재시작 - 트래픽 증가에 따른 클러스터 확장 - 무중단 운영을 유지한 운영체제 업그레이드 - 새 ScyllaDB 버전을 검증하기 위한 신규 클러스터 생성 - 작업 간 순서와 검증이 중요하기 때문에 단순한 일회성 자동화만으로는 부족하다. ## 기존 스크립트의 한계 - Python과 Bash 스크립트를 점진적으로 추가해 왔지만, 운영 규모가 커지면서 도구가 취약해졌다. - 스크립트가 제공하던 문제점은 다음과 같다. - **안전하지 않음:** 잘못된 순서나 대상 노드에 실행할 수 있고, 실행 전 조건 확인이 부족했다. - **복구 불가능:** 여러 단계 중간에 실패하면 완료한 작업까지 되돌리거나 전체 작업을 처음부터 다시 해야 했다. - **확장하기 어려움:** 새 작업을 추가할 때 기존 스크립트를 복사하고 수정하는 방식이 필요했다. - 운영에 필요한 절차와 노하우가 개별 엔지니어의 경험에 의존했다. ## Shadow Cluster를 통한 안전한 업그레이드 검증 - Shadow cluster는 운영 클러스터의 전체 복제본으로, 짧은 기간 동안 실제 운영 트래픽의 읽기와 쓰기를 함께 처리한다. - 운영 환경에 영향을 주기 전에 다음과 같은 문제를 실제 부하에서 발견할 수 있다. - 특정 ScyllaDB 버전의 예외적인 동작 - 대규모 클러스터에서만 발생하는 버그 - 모든 노드 업그레이드 후에야 나타나는 문제 - 신규 shadow cluster를 수동으로 만들려면 다음 절차를 반복해야 했다. - 노드 프로비저닝 및 설정 - 노드를 클러스터에 순차적으로 조인 - 복제 상태 검증 - dual-write 파이프라인 구성 - 테스트 후 리소스 제거 - Discord는 ScyllaDB 버전뿐 아니라 운영체제와 하드웨어 변경 전에도 shadow cluster를 표준 검증 절차로 활용한다. ## SCP 설계 목표 SCP는 기존 운영 경험에서 얻은 문제를 바탕으로 다음 네 가지 목표를 세웠다. - **확장 가능한 태스크 프레임워크** - 작업의 입력과 실행 로직만 정의하면 기존 오케스트레이션 환경에서 동작하도록 설계한다. - 새로운 개발자가 내부 실행 구조를 모두 이해하지 않아도 새 작업을 추가할 수 있어야 한다. - **설정 가능한 병렬성** - 여러 노드에서 동시에 실행해도 되는 작업과 순차 실행이 필요한 작업을 구분한다. - 예를 들어 서로 다른 availability zone의 노드에서 특정 작업을 동시에 실행하지 않도록 제약을 표현할 수 있다. - **기본적으로 안전한 실행** - 태스크가 실행 전제 조건을 직접 선언한다. - 일시적 오류는 자동으로 재시도한다. - 실행 상태를 저장해 중단된 작업을 완료 지점부터 재개한다. - **점진적 개발과 배포** - 처음부터 거대한 시스템을 만들기보다 사용할 수 있는 기능부터 배포한다. - 실제 클러스터에서 사용하며 온보딩과 사용성 문제를 조기에 발견하고 개선한다. - 사용되지 않는 복잡한 프레임워크를 만드는 일을 피한다. ## SCP의 기본 구조 SCP는 **태스크(task)**, **워크플로(workflow)**, **잡(job)**이라는 계층적 개념을 중심으로 구성된다. - **태스크** - 하나의 구체적인 작업 단위다. - 예: 노드 drain, repair 상태 확인, 정리 작업 실행 - 단일 노드에서 실행되는 **노드 태스크**와 클러스터 전체를 조정하는 **클러스터 태스크**로 나뉜다. - 클러스터 태스크는 여러 노드에서 노드 태스크를 실행하는 역할도 담당한다. - **조건(condition)** - 다음 태스크로 넘어가기 전에 클러스터가 특정 상태에 도달했는지 확인하는 특수한 태스크다. - Scylla API나 Prometheus 메트릭을 주기적으로 조회한다. - 조건이 충족되면 진행하고, 제한 시간 안에 충족되지 않으면 오류를 발생시킨다. - **명시적인 상태 대기** - 노드 재시작 후에는 compaction이 안정될 때까지 기다려야 한다. - 고정된 `sleep`만 사용하면 대기 시간이 너무 짧아 장애를 일으키거나, 너무 길어 전체 롤링 재시작이 불필요하게 느려질 수 있다. - 조건 태스크는 대기 과정을 관찰 가능하고 조정 가능하게 만든다. ## 실용적인 결론 대규모 데이터베이스 운영에서는 개별 스크립트를 계속 늘리기보다, 작업의 선행 조건·재시도·상태 저장·병렬 실행 규칙을 표준화한 오케스트레이션 계층이 필요하다. 특히 운영 트래픽을 재현하는 shadow cluster와 재개 가능한 태스크 프레임워크를 결합하면, 위험한 업그레이드를 자동화하면서도 실패 복구 비용을 크게 줄일 수 있다.

discord

새로운 Rust 상점에서 아이템을 쟁여두세요! 5월 21일까지 대부분의 아이템을 디스코드 전용 20% 할인으로 만나보세요 (새 탭에서 열림)

Discord에 공식 Rust 아이템을 구매하고 선물할 수 있는 **Rust Shop**이 출시됐다. 사용자는 Discord Shop이나 공식 Rust 서버에서 스킨·장식·코스메틱을 구매해 Rust 인벤토리로 바로 받을 수 있으며, 이번 출시로 공식 스킨 선물도 처음 지원된다. 출시 기념으로 2026년 이전에 출시된 대부분의 공식 Rust 스킨은 5월 21일까지 Discord에서만 20% 할인된다. ## Discord에서 Rust 아이템 구매 - 데스크톱 또는 웹 Discord에서 Rust 아이템을 구매할 수 있다. - 접근 경로는 두 가지다. - Discord Shop 상단의 **Game Shops** - 공식 Rust 서버 채널 목록 상단의 **Game Shop** - 구매한 아이템은 Rust 인벤토리로 직접 전달된다. - Rust 계정과 Discord 계정이 이미 연결되어 있다면 별도 설정 없이 이용할 수 있다. - 계정이 연결되지 않았다면 결제 후 몇 번의 클릭으로 연동할 수 있다. - Rust Shop과 Game Shops는 글 작성 시점 기준으로 모바일 앱에서는 지원되지 않는다. ## 공식 Rust 스킨 출시 할인 - 2026년 이전에 출시된 거의 모든 공식 Rust 스킨이 할인 대상이다. - 할인율은 Discord 한정 **20%**다. - 할인 기간은 출시일인 5월 7일부터 **5월 21일까지**다. - 할인 대상에는 장식 아이템, 코스메틱 세트, 각종 아이템 스킨 등이 포함된다. ## Discord 친구에게 Rust 아이템 선물 - Discord는 Rust 공식 아이템의 선물 기능을 처음 지원한다. - 친구 프로필의 **Wishlist** 탭에서 친구가 원하는 Rust 아이템을 확인할 수 있다. - 원하는 아이템을 찾은 뒤 몇 번의 클릭으로 바로 선물할 수 있어 취향을 추측할 필요가 없다. - 선물 기능은 여러 위치에서 제공된다. - 친구 프로필의 Wishlist - DM의 선물 아이콘 - Rust Shop의 아이템 페이지 - 채팅에 공유된 Rust 아이템 링크 - Rust를 함께 스트리밍하는 중의 Discord 인터페이스 ## 이용 시 참고 사항 - Rust와 Discord 계정 연동이 구매 및 아이템 수령에 필요하다. - PC 또는 웹 버전 Discord를 사용해야 한다. - 구매 전 친구의 Wishlist를 확인하면 원하는 스킨을 정확히 선물할 수 있다. - 할인은 5월 21일에 종료되므로 구매를 계획한다면 기간을 확인해야 한다. 이번 업데이트는 Rust 아이템 구매와 선물을 Discord 커뮤니티 안으로 통합한 기능이다. Rust를 즐기는 사용자라면 계정을 먼저 연동하고 Wishlist를 활용해 할인 기간에 필요한 스킨이나 친구 선물을 구매하는 것이 실용적이다.

discord

Discord 패치 노트: 2026년 5월 4일 (새 탭에서 열림)

Discord의 2026년 5월 4일 패치 노트는 성능·안정성·사용성 개선과 다양한 버그 수정을 다룬다. 특히 서버 관리 및 권한 관련 문제를 집중적으로 해결했고, Android 동영상 시작 속도와 Soundboard 접근성을 개선했다. 데스크톱 설정 구조를 단순화하고 Linux 자동 업데이트도 지원해 전반적인 사용 편의성을 높였다. ## 서버 관리와 권한 문제 개선 - 서버 관리자용 기능에서 권한, 사용자 상태, 계정 안전 기능과 관련된 여러 오류를 수정했다. - Community 설정의 “Discord 관리자 서버 참여” 팝업을 닫아도 나중에 다시 참여할 수 있도록 버튼이 사라지지 않게 했다. - 서버 부스트 결제 화면에서 `ESC`를 눌렀을 때 결제 창이 아니라 뒤쪽의 부스트 페이지가 닫히던 문제를 해결했다. - 서버 프로필 편집 중 저장하지 않은 변경 사항이 있을 때, 모달 바깥을 클릭해도 경고 없이 닫히지 않도록 동작을 개선했다. - 서버별 프로필의 대명사를 지울 때 기본 프로필의 대명사가 자동 입력되던 문제를 수정하고, 기본 대명사는 placeholder로 표시한다. - 서버별 아바타의 링크를 복사할 때 기본 프로필 아바타 링크가 복사되던 문제를 해결했다. ## Android 동영상과 모바일 성능 - Android의 동영상 전송 네트워크 스택을 추가로 조정했다. - Android에서 동영상 피드가 시작되는 속도가 약 4.89% 빨라졌으며, 평균 시작 시간이 600ms 미만으로 줄었다. - 모바일에서 검색 결과를 불러오는 중 연결이 끊겼을 때 오류 메시지가 반복 표시되거나 요청을 무한 재시도하던 문제를 수정했다. - Media, Pins, Files, Links 탭에서 네트워크 오류가 발생해도 불필요한 재시도가 반복되지 않는다. - Android 검색 필터가 활성화되어도 파란색으로 표시되지 않던 시각적 문제를 해결했다. - iOS에서 프로필 또는 앱 소개의 링크를 눌렀을 때 발생하던 충돌을 수정했다. - iOS에서 기본 프로필의 사용자 이름을 복사한 뒤 서버별 프로필 화면으로 되돌아가던 문제도 해결했다. ## 데스크톱 설정 구조 개편 - 기존 Appearance, Accessibility, Chat, Streamer Mode, Advanced 설정을 다음 세 페이지로 통합했다. - Appearance - Accessibility - Developer - 일부 설정의 배치와 문구를 명확하게 변경했다. - “Sync Themes Across My Devices”를 다시 활성화했을 때 현재 테마가 이전에 동기화된 테마로 되돌아가던 문제를 수정했다. - 최근 아바타에 마우스를 올렸을 때 삭제 버튼이 보이지 않던 문제를 해결했다. - 프로필 편집 모달의 저장 변경사항 표시줄이 Legacy Username Badge 토글과 겹치던 문제를 수정했다. - “Connect Your Domain” 화면의 버튼 간격이 지나치게 좁거나 가장자리에 붙던 레이아웃 문제를 개선했다. - 프랑스어 환경에서 Poll 검색 필터인 `sondage`가 `Son`과 `dage`로 잘못 분리되던 문제를 해결했다. ## Soundboard와 음성 채널 로딩 - Soundboard 데이터를 처음 열 때가 아니라 음성 채널에 참가할 때 미리 가져오도록 변경했다. - 그 결과 음성 통화 중 Soundboard를 처음 사용할 때의 로딩 시간이 줄었다. - 작은 로딩 속도 개선만으로도 Soundboard 효과 사용량이 측정 가능하게 증가했다고 설명한다. ## Linux 업데이트와 패키지 지원 - Windows에서 사용하던 Rust 기반 자동 업데이트 시스템을 Linux에도 적용했다. - 이제 Linux 사용자는 새 버전을 직접 내려받아 설치하지 않고 앱 자체에서 업데이트할 수 있다. - 설치 패키지 형식으로 `.rpm`과 `.pkg.tar.zst`도 추가 지원한다. ## 기타 일반 버그 수정 - “Copy Username” 기능의 `GODLIKE!!`, `BEYOND GODLIKE!!` 메시지 배경이 투명하게 보이던 문제를 수정했다. 배경색은 기존 빨간색 대신 초록색으로 통일했다. - Quick Switcher에 초대 링크를 붙여 넣으면 해당 서버에 참가하고 바로 이동할 수 있게 됐다. - Active Now 창에서 사용자 이름에 마우스를 올릴 때 상태 표시기가 흰색으로 변하던 문제를 해결했다. - 모바일 검색 결과에서 긴 닉네임이 메시지 타임스탬프를 가리던 문제를 수정했다. - Server Boost 홍보 화면의 오디오가 결제 흐름으로 이동한 뒤에도 계속 재생되던 문제를 해결했다. - 알림을 빠르게 여러 개 삭제할 때 Inbox가 충돌하던 문제를 수정했다. - Nitro 탭에서 Nitro 가입 기간 보상 배지를 눌러도 사라지지 않던 문제를 해결했다. - 구독 설정에서 `GBP` 통화명이 비어 보이던 문제를 수정했다. - Inbox의 Unreads 미리보기에서 만료된 공개 이미지 링크가 표시되지 않던 문제를 해결했다. - 친구 요청 이메일에 오래된 `#0` discriminator가 표시되던 문제를 수정했다. - Nitro 체험 대상 친구를 선택하는 체크박스가 실제로 선택되지 않던 문제를 해결했다. - 사용자 프로필에서 Custom Status 편집 창을 열 때 전체 프로필을 대체하지 않고 위에 표시되도록 변경했다. - 프로필, 서버 부스트, 검색, 알림, 결제 등 여러 화면의 모달·버튼·레이아웃 관련 세부 오류를 정리했다. ## 적용 일정과 테스트 참여 - 모든 수정 사항은 코드에 반영되고 병합되었지만, 플랫폼별로 실제 배포되는 시점은 다를 수 있다. - 사용자는 커뮤니티의 격월 버그 메가스레드에 문제를 신고할 수 있다. - iOS 사용자는 TestFlight 버전에 참여해 정식 출시 전 기능과 수정 사항을 시험할 수 있다. 이번 업데이트는 대규모 신기능보다 서버 관리자 기능의 신뢰성, 모바일 성능, 설정 탐색성, 플랫폼별 업데이트 편의성을 높이는 데 초점을 맞췄다. Discord를 관리하거나 Android·Linux·데스크톱 앱을 주로 사용하는 사용자는 업데이트 후 관련 기능의 개선 여부를 확인해 보는 것이 좋다.

cloudflare

신뢰할 수 있는 Rust Worker 만들기: wasm-bindgen에서의 패닉 및 중단 복구 (새 탭에서 열림)

Cloudflare Workers 환경에서 Rust로 작성된 WebAssembly(Wasm)는 예기치 못한 패닉(Panic)이나 중단(Abort)이 발생할 경우 런타임이 정의되지 않은 상태로 남아 동일한 인스턴스의 다른 요청까지 실패하게 만드는 '샌드박스 오염' 문제를 안고 있었습니다. 이를 해결하기 위해 Cloudflare는 `wasm-bindgen` 메인 프로젝트와 협력하여 Wasm 예외 처리 기능을 활용한 `panic=unwind` 지원과 중단 복구 메커니즘을 도입했습니다. 결과적으로 단일 요청의 실패가 전체 서비스 중단으로 이어지는 것을 방지하고, 상태 유지가 필요한 애플리케이션에서도 안정적인 오류 복구가 가능해졌습니다. ### 초기 대응 및 완화 전략 본격적인 기능 개선에 앞서, Cloudflare는 운영 환경에서의 피해를 최소화하기 위해 사용자 정의 패닉 핸들러와 JavaScript 프록시를 활용한 초기 완화책을 적용했습니다. * **패닉 핸들러 도입:** Rust 내부에 상태를 추적하는 패닉 핸들러를 설치하여 실패가 발생하면 전체 애플리케이션을 다시 초기화하도록 설정했습니다. * **Proxy 기반 간접 참조:** JavaScript 영역에서 Rust 호출 경계를 `Proxy`로 감싸 모든 진입점을 캡슐화하고, 실패 시 안전하게 Wasm 모듈을 재로드했습니다. * **한계점:** 이 방식은 서비스 가용성은 높였으나, 전체 애플리케이션을 재시작해야 하므로 메모리에 상태를 보관하는 Durable Objects 같은 서비스에서는 데이터 손실이 발생하는 단점이 있었습니다. ### Wasm 예외 처리를 통한 panic=unwind 구현 상태를 보존하면서 오류를 복구하기 위해 Wasm의 최신 표준인 예외 처리(Exception Handling) 제안을 활용하여 Rust의 패닉 언와인딩(Unwinding)을 구현했습니다. * **컴파일 옵션 변경:** `RUSTFLAGS='-Cpanic=unwind'`와 `-Zbuild-std`를 사용하여 표준 라이브러리가 언와인딩을 지원하도록 다시 빌드했습니다. * **wasm-bindgen 툴체인 업데이트:** Wasm 파서인 Walrus가 `try`, `catch`, `rethrow` 명령어를 인식하도록 수정하고, JavaScript와 Rust 경계에서 예외가 올바르게 전달되도록 개선했습니다. * **Boundary 처리:** Rust에서 발생한 패닉이 JavaScript의 `PanicError`로 변환되도록 했으며, `extern "C-unwind"`를 통해 함수 호출 경계를 넘나드는 언와인딩을 허용했습니다. * **클로저 안전성:** `MaybeUnwindSafe` 트레잇을 도입하여 언와인딩 시 안전하지 않은 참조를 캡처하는 클로저를 체크하고, 필요한 경우 패닉 시 즉시 중단되는 `Closure::new_aborting` 변형을 제공합니다. ### 중단(Abort) 복구 및 포이즌 필(Poison Pill) 메커니즘 메모리 부족(OOM)과 같이 언와인딩이 불가능한 '중단' 상황에서는 메모리 상태가 오염될 가능성이 높기 때문에, 해당 인스턴스의 재실행을 원천 봉쇄하는 전략을 사용합니다. * **포이즌 필 플래그:** `wasm-bindgen`은 이제 모든 Wasm 모듈에 내부 상태 플래그를 주입합니다. 만약 Rust 코드에서 중단이 발생하면 이 플래그가 즉시 설정됩니다. * **재실행 방지:** 이후 JavaScript에서 해당 Wasm 인스턴스의 어떤 함수라도 호출하려고 하면, Rust 코드를 실행하기 전에 플래그를 먼저 확인하여 즉시 JavaScript 에러를 발생시킵니다. * **안전성 보장:** 이를 통해 오염된 메모리 상태에서 코드가 다시 실행되어 발생할 수 있는 보안 취약점이나 예측 불가능한 동작을 완전히 차단합니다. Wasm 기반의 Rust 서비스를 운영한다면 최신 버전의 `wasm-bindgen`과 `workers` 라이브러리를 사용하고, 특히 Durable Objects와 같이 상태 보존이 중요한 경우 `panic=unwind` 설정을 활성화할 것을 권장합니다. 이는 단순한 안정성 향상을 넘어, Wasm이 네이티브 환경과 동등한 수준의 오류 복구 능력을 갖추게 되었음을 의미합니다.

cloudflare

Unweight: 품질 저하 없이 LLM을 22% 압축한 방법 (새 탭에서 열림)

Cloudflare는 LLM의 가중치를 15~22% 압축하면서도 출력 결과의 정확도를 비트 단위로 완벽하게 보존하는 무손실 압축 시스템인 'Unweight'를 공개했습니다. 이 시스템은 NVIDIA H100 GPU의 연산 능력에 비해 현저히 느린 메모리 대역폭 병목 현상을 해결하기 위해 설계되었으며, 추론 시 가중치를 고속 온칩 메모리(Shared Memory)에서 직접 해제하여 처리 효율을 극대화합니다. 결과적으로 Llama-3.1-8B 모델 기준 약 3GB의 VRAM을 절약함으로써, 품질 저하 없이 더 적은 자원으로 더 빠른 추론 서비스를 제공할 수 있게 되었습니다. ### 메모리 대역폭 병목 현상과 무손실 압축의 필요성 * **컴퓨팅-메모리 불균형:** NVIDIA H100의 텐서 코어는 메모리가 데이터를 전달하는 속도보다 약 600배 빠르게 데이터를 처리할 수 있어, 추론 속도의 핵심은 '메모리 버스를 통과하는 데이터양'을 줄이는 데 있습니다. * **양자화의 한계:** 4비트나 8비트 정수로 변환하는 기존 양자화 방식은 손실 압축(Lossy)이므로 모델의 응답 품질을 예측할 수 없게 만듭니다. * **무손실 아키텍처:** Unweight는 비트 단위로 동일한(Bit-exact) 출력을 보장하면서도 가중치 크기를 줄여, 서비스 품질을 타협하지 않고 하드웨어 효율성만 높였습니다. ### BF16 지수(Exponent) 데이터의 중복성 활용 * **데이터 구조 분석:** BF16 가중치는 부호(1비트), 지수(8비트), 가수(7비트)로 구성되는데, 이 중 부호와 가수는 무작위성이 강해 압축이 어렵지만 지수 부분은 매우 높은 중복성을 보입니다. * **지수 분포의 편향성:** 일반적인 LLM 레이어에서 가장 빈번하게 등장하는 상위 16개의 지수 값이 전체 가중치의 99% 이상을 차지한다는 점에 착안했습니다. * **허프만 코딩(Huffman Coding) 적용:** 정보 이론에 따라 빈도가 높은 지수에는 짧은 코드를, 낮은 지수에는 긴 코드를 할당하는 허프만 코딩을 통해 지수 스트림에서 약 30%의 압축률을 달성했습니다. ### GPU 온칩 메모리를 활용한 효율적 압축 해제 * **SMEM 직접 해제:** 압축된 가중치를 느린 메인 메모리(HBM)로 다시 돌려보내지 않고, 텐서 코어 바로 옆의 빠른 공유 메모리(SMEM)에서 즉시 해제하여 연산에 투입함으로써 추가적인 지연 시간을 방지합니다. * **선택적 적용:** 모델 파라미터의 약 2/3를 차지하며 메모리 트래픽의 주원인인 MLP(Multi-Layer Perceptron) 가중치 행렬에 집중적으로 적용하여 효율을 높였습니다. * **행 단위(Row-based) 최적화:** 64개 가중치로 구성된 한 행에 희귀 지수가 하나라도 포함되면 해당 행 전체를 무압축 상태로 저장하여, 커널 실행 시 복잡한 분기 처리를 줄이고 처리 속도를 최적화했습니다. ### 실용적인 결론 및 권장사항 Unweight는 모델의 정확도를 1%도 포기할 수 없으면서 VRAM 부족 문제를 해결해야 하는 고성능 추론 환경에 최적화된 솔루션입니다. 특히 NVIDIA Hopper 아키텍처(H100 등)를 사용하는 환경에서 Llama-3.1-8B와 같은 모델을 운용할 때 약 3GB의 메모리 여유 공간을 확보할 수 있어, 더 큰 배치 사이즈를 운용하거나 더 많은 모델을 하나의 GPU에 올리는 데 유용합니다. Cloudflare는 이 기술의 확산을 위해 기술 논문과 함께 GPU 커널을 오픈소스로 공개하였습니다.