Software Engineer · AI/ML Engineer

Explore and Dream Big

I build systems end to end. From training transformers and inference to systems architecture and deployment.

Featured Technologies

My Featured Tech Stack

I build software, systems, and train transformer models utilizing these languages, tools, and frameworks in my daily workflows.

Languages

  • Python
  • C++

AI / ML

  • PyTorch
  • Transformers
  • Hugging Face

Backend

  • REST APIs
  • FastAPI

Cloud & Infrastructure

  • AWS
  • Terraform
  • Docker
  • GitHub Actions

Tools

  • SQL
  • Linux
  • Git + GitHub
  • SDL
Current Project

System Architecture

Diagram: Current state of my website's system architecture. AWS for Cloud Infrastructure. GitHub Actions for CI/CD.
Last updated: Sept 2026

AWS · US-EAST-1 live request release / control model artifact RELEASE / ARTIFACT CONTROL LIVE REQUEST PATH MODEL LIFECYCLE GitHub Actions test, build, smoke OIDC role Amazon ECR immutable website digest SSM · production pointer deploys that digest Browser alexander-choi.com Route 53 DNS only CloudFront stable public front door WAF ACM Function + KVS · active_runtime DNS resolution HTTPS request ACTIVE Elastic Beanstalk SingleInstance · nginx · no EB LB Pros: Cost Savings · Cons: Less scalable Docker Image → Uvicorn / FastAPI single application process PARKED ECS / Fargate alternate ALB, tasks and paid interface endpoints absent while parked Pros: More scalable · Cons: More expensive Docker Image → Uvicorn / FastAPI same digest as the EB runtime selected origin alternate SageMaker 2 serverless endpoints ACAI · 152.6M Translator · 3.36M API THE MODELS Two transformers ACAI 152.6M decoder-only d768 · 18 layers pre-norm · RoPE TRANSLATOR 3.36M encoder–decoder d128 · 2+2 layers post-norm architectures, not deployments GitHub My model architecture repositories live here Runpod Cloud GPU compute Powers my model training Amazon S3 model.tar.gz per model, versioned Amazon ECR inference images one per model weights + image → SageMaker Model
open ← overview Request & Inference Path AWS · US-EAST-1 Browseralexander-choi.com Route 53DNS only, no proxying CloudFront permanent public front door WAF ACM Function reads KVS · active_runtime ACTIVE Elastic Beanstalk SingleInstance · no EB load balancer · nginx on host Pros: Lower cost · Cons: Less scalable Docker image → Uvicorn / FastAPI the application is content inside the runtime InferenceCoordinator ×2 warms, then generates PARKED ECS / Fargate alternate Pros: More scalable · Cons: Higher Cost ALB + service/tasks absent while parked When active: ALB → Fargate ×2 → private subnets, X-Origin-Verify header locks the origin to CloudFront Docker image → Uvicorn / FastAPI same digest as the EB runtime InferenceCoordinator ×2 absent while parked selected origin VPC endpoints Private subnets only — the ECS path S3 gateway endpoint is free and persists while ECS is parked. Interface endpoints for ecr, logs, ssm, sagemaker.runtime are billed hourly and exist only with ECS. SageMaker Runtime Two serverless endpoints Always on, independent of EB or ECS 6144 MB · scale to zero when idle MaxConcurrency = 1 is current chosen serving Pros: Cost savings. Cons: Less scalable Switching runtimes changes one KVS value. Route 53 and the CloudFront distribution never move, so public DNS and the certificate stay stable across a switch.
open ← overview Build, Release & Runtime Switching NORMAL WEBSITE RELEASE — GITHUB ACTIONS AWS · US-EAST-1 GITHUB · HOSTED RUNNER 1 pytest tests 2 build Docker image 3 smoke test exact image 4 push ECR via OIDC 5 digest immutable URI 6 read KVS which runtime is live 7 deploy that digest only 8 validate SSM pointer last SECURITY GitHub OIDC assumes a scoped role per job; no long-lived AWS keys live in either repository. ARTIFACT INVARIANT The image that passed CI is the image deployed. The pointer advances only after smoke validation. TRANSACTIONAL RUNTIME SWITCH — EB ↔ ECS AWS · US-EAST-1 Current runtime keeps serving throughout Hydrate target Terraform creates it Deploy digest the SSM-approved image Preview smoke through a CloudFront token Flip KVS active_runtime = target Public smoke then a 60 s drain Park old runtime only after validation FAILURE RULE Before cutover no public rollback is needed — the old runtime never stopped serving. After cutover but before parking, flip KVS back immediately and leave both runtimes intact for diagnosis. This pipeline covers website CI. Infrastructure deployment via Terraform.
open ← overview Model Lifecycle AWS · US-EAST-1 GitHub My model repositories live here RunPod Cloud GPU rented compute Powers model training, Pod spinup, pull, and train Amazon S3 versioned model.tar.gz weights + config + tokenizer Amazon ECR versioned inference image serving code + runtime SageMaker Model binds the S3 artifact and the ECR image plus the execution role EndpointConfig serverless variant memory + concurrency name from a fingerprint Endpoint stable name, the only thing the website consumes TWO INDEPENDENT VERSION AXES model_version→ S3 weights, tokenizer, config image_version→ ECR serving code and runtime WHY IT MATTERS Weights and serving code move independently. Terraform fingerprints the material inputs, so a changed variant forces a fresh Model and EndpointConfig before the stable endpoint is repointed. ACAI — model 1.0.0, image 1.0.2 OWNERSHIP & STATUS ACAI own Terraform state · serverless Max Concurrency: 1 English → German infra/ml/translator state stable endpoint name, own lifecycle Each endpoint owns its state, IAM role, ECR lifecycle policy, log group and 5xx alarm. The website consumes only the endpoint name.
Current Project

Transformer Language Models

Transformer models written from scratch in PyTorch.
Last updated: Sept 2026

ACAI · DECODER-ONLY 152.6M d_model 768 · 18 layers · 12 heads · d_ff 2048 · context 2048 · vocab 32,768 Token embedding tied to output projection RMSNorm pre-norm Causal self-attention RoPE + KV cache RMSNorm pre-norm SwiGLU gated feed-forward Final RMSNorm → logits REPEATED BLOCK ×18 RMSNorm RoPE causal attention residual RMSNorm SwiGLU residual SERVING NOTE KV cache at 2048 tokens ≈ 113 MB/sequence at bf16 (decimal MB). This is meaningful per-request memory, but it does not itself set SageMaker MaxConcurrency. MaxConcurrency=1 is the current serving policy around which the coordinator is built. ENGLISH → GERMAN · ENCODER–DECODER 3.36M d_model 128 · 2 encoder + 2 decoder · 4 heads · d_ff 512 · dropout 0.2 output probabilities · greedy generation Softmax Linear → 5,000 target vocabulary logits Multi-Head Attention self-attention · 4 heads Add & Norm Feed Forward d_ff 512 · GELU Add & Norm Masked Multi-Head Attention self-attention · 4 heads Add & Norm Multi-Head Attention cross-attention · K,V from encoder Add & Norm Feed Forward d_ff 512 · GELU Add & Norm ×2 ×2 K, V ⊕ sinusoidal positional encoding ⊕ sinusoidal positional encoding EN BPE · 4,000 input embedding · ×√d_model DE BPE · 5,000 output embedding · shifted right
Featured Publication

Research at EMNLP

The LLM Effect: Are Humans Truly Using LLMs or Are They Being Influenced By Them Instead?

Alexander S. Choi, Syeda Sabrina Akter, JP Singh, Antonios Anastasopoulos

Large Language Models (LLMs) have shown capabilities close to human performance in various analytical tasks, leading researchers to use them for time and labor-intensive analyses. However, their capability to handle highly specialized and open-ended tasks in domains like policy studies remains in question. This paper investigates the efficiency and accuracy of LLMs in specialized tasks through a structured user study focusing on Human-LLM partnership. The study, conducted in two stages—Topic Discovery and Topic Assignment—integrates LLMs with expert annotators to observe the impact of LLM suggestions on what is usually human-only analysis. Results indicate that LLM-generated topic lists have significant overlap with human generated topic lists, with minor hiccups in missing document-specific topics. However, LLM suggestions may significantly improve task completion speed, but at the same time introduce anchoring bias, potentially affecting the depth and nuance of the analysis, raising a critical question about the trade-off between increased efficiency and the risk of biased analysis.

Game Development

Building a Game Engine from Scratch.

A custom game engine built in C++, exploring low-level rendering, game systems, architecture, and interactive application development.

  • C++
  • SDL
Explore the AChoiEngine.