#CS
Did you know that the transformer—the architecture underlying nearly every modern AI model, including physical AI—was originally developed for machine translation 1 ? It has been almost five years since I launched this website and I've written more than 100 posts since then. But my foreign friends probably don't know that, because unlike the rest of the website, the blog has only been in Korean. I haven't had the time to translate every post as I write it. So ever since translation was one of the few things AI could do reasonably well, years before it became capable of nearly everything, I've wanted to build a pipeline that would leverage it to translate my posts automatically. I put it off for more than two years, not being able to even find the time to do so. But finally after spending a little time and some tokens, I just added it to the website as a new feature. Coding agents really have gotten good—I built it in no time. Now, if you set the site language to English, you'll see translated posts instead of the Korean originals. It will be a different experience from simply running the originals through Google Translate or DeepL. The translations follow instructions I've tailored to my preferences and I review them afterward. More importantly, I believe there's a big difference between having a post that is already readable and having to press a button to make it understandable. That's probably why X (formerly Twitter) recently made the big decision to translate all posts and replies proactively. This will be the first post translated that way. Earlier posts will be translated soon, too. To all my friends around the world: let's make use of modern technology to bring us a little closer together. 1 More precisely, sequence transduction, which includes machine translation.
1y ago · #CS #웹개발
The title looks a bit intimidating... but that's what happened when I translated the original English title literally. Yesterday, I noticed that my GitHub repos had passed thirty, so I was clearing out the ones I didn't need when one repo caught my eye. Once I got comfortable with git in the later years of my undergraduate degree, I started backing up the original code for programming assignments on GitHub, and this was one of them. It was the second assignment for [AI-Based Software Engineering], a course I took in fall 2021. We had to find a real-world problem suited to metaheuristic search and implement a solver for it. It's only been two years, but I'd forgotten everything about it. I read through the report with the curiosity I'd have for something written by someone else, and, to my surprise, it was pretty interesting. I'd chosen the topic after thinking about the Line 9 express train I took all the time between my home in Seoul and the Express Bus Terminal, where I caught the bus to Daejeon. The way I developed the idea felt surprisingly fresh. It's a little embarrassing to say that about my own work, but that was my impression on rereading it after so long. So, for my own satisfaction, I decided to put it on the blog too. Haha. Assignments that let students choose their own topics are a double-edged sword for their growth. A creative choice the professor never anticipated can help you develop your skills enormously; on the other hand, you can make a complete mess of it without much chance of serious consequences. Luckily, most of those assignments seem to have worked out in ways that helped me. This one is relatively ordinary. Looking back, several assignments where I picked an even stranger topic, cursed my past self, and somehow forced my way through ended up helping me grow even more. Building a two-way communications satellite, developing a 2D reusable-rocket landing system, and so on... lol. I hope I'll get to tell those stories here someday too. ⋮ The assignment submission consists of the solver and report in the GitHub repo below. It takes finding the minimum-time path through a metro line with multiple levels of express service as its real-world problem and shows how to solve it through metaheuristic search using a genetic algorithm. 🔗 GunheeYi/cs454-ass2 — Github Repository Report (Slightly revised from the submitted version) 2021 Fall CS454 at KAIST Assignment 2: Solving Minimum-Time Path Problem in a Metro System Involving Multiple Levels of Express Lines, Using Genetic Algorithms Gunhee Yi (20180431) In almost every weekend I take the line 9 of Seoul Metro. It conveniently connects the Express Bus Terminal and my town, and the 18 minutes that I spend there becomes the last step of the long journey from KAIST in Daejeon to my home in Seoul. 18 minutes, that is the time when I take the express train. There are both express and local trains in line 9. It takes 30 minutes if I take the local train, so it is better to take the next express rather than the local one even if I just missed the express. Though knowing that already, I still check the metro app often to see the arrival time of the next train. Then one day, as I was staring blankly through the screen, I started wondering about the cases where the departing or arriving stations were not express stations. In these cases, going forward some local stations before/after getting in/out of an express train was a common doing. But what if going BACK a little actually earned you some time? It turns out that it is not the case in line 9. Refer to the following deduction: Settings: $s_1$ is a local station right after the express station $s_0$. There are $n$ local stations between $s_0$ and another express station $s_{n+1}$. You are now at $s_1$ and desires to reach $s_{n+1}$. It takes constant $l$ minutes for a local train to move 1 station. It takes $e$ minutes for an express train to move from $s_0$ to $s_{n+1}$. Going forward for $n$ local stations takes $ln$ minutes, whereas going back a station and taking the express takes $(l+e)$ minutes. If the backward route is to be better, it should be $l+e There are not any adjacent pairs of express stations in line 9 that has more than two local stations in-between, so going back should never be an option for the passengers. But further search revealed that there was another line that had expresses. It was line 1, and its expresses passed through well over 10 stations during their operation. Now that we have found a real-world example that going back would actually benefit us, many path-finding algorithms may fail or struggle to utilize the fact. Take a greedy algorithm for example, which picks a path that is now possible and most decreases the distance to destination at a constant time. It will never try going back because it increases both the distance and time taken, in short sight. An algorithm that looks through every possible routes, will succeed on finding the optimal path but will still struggle, for two reasons. First, the capability of going back practically doubles the number of edges. Most of the path finding algorithms has a time complexity proportional to this number, so the solving time will double as well. Second, loop is newly introduced. A loop may cause the path finder to iterate in it indefinitely and fail eventually, so we should modify the algorithm to detect and exclude loops from its routes. This is where I thought the genetic algorithm could come to place. In a problem like this, we expect that suboptimal solutions will be a lot alike with the actual optimal solution. And in alike I mean that their paths are likely to be the same part by part. This is what the genetic algorithm directly looks for. By some predefined methods, my genetic algorithm will try to preserve the optimal part of genes (that is, sub-paths in this case) and try new types in other parts. By doing this, the genetic algorithm exceeds other algorithms in that it retains some memories and only tries solutions that are likely to be good, using prior memories. There is also some factor of "exploration" such that the solver lies not only in local optimums. One may argue that even though the amount of calculation increases due to the addition of reverse ways, it is still in a manageable range for the traditional algorithms and a modern computer to handle if the number of stations is limited to about the magnitude of a single metro line. I was also convinced by this self-argument, so I decided to complicate the problem in a useful way: adding multiple levels of expresses. There won't be many metro systems that has multiple levels of expresses in a single line, but we can think of it as an analogy of the whole transportation system that involves not only metros but also buses, trains and even airliners. Level 0 should be the slowest means such as town buses, and the highest level should be the airliner. This kind of expansion will allow the problem to be applied to a system not only with higher levels, but also with bigger number of "stations" (Think about the number of stations that you would have to pass if you were to travel from Seoul to Busan only on town bus!), where traditional algorithms will begin to fall. Now that I have pictured the problem, I formulated into a real set of stations and local/express lines. Refer to the following: <div class="mon
2y ago · #CS
People sometimes ask me about the tech stack behind BuyBus, so I thought I’d put it all together. This will probably be obvious to experienced developers, but I’ve tried my best to include everything. I hope it’ll be useful to anyone who’s vaguely imagined building something similar but hasn’t known where to start. There are three diagrams in total. The one at the top is an overview covering my development environment, the server, users’ devices, and third parties like AWS, Google, and PayPal. The two below it zoom in on the server and client parts of that overview, respectively. All three are vector graphics, no less! I generated the detailed server and client architecture diagrams automatically with an npm package called dependency-cruise, and made the overview myself in Figma. Figma’s auto layout let me draw the nested elements neatly, but I wasn’t sure what to do about the arrows: vanilla Figma doesn’t automatically update an arrow’s endpoints when the elements it connects move. Then I installed a plugin called Arrow Auto, and it worked like a charm. Figma rules. The automatically generated server and client architecture diagrams look a bit intimidating, but they’re not as hard to make as they look. You make server requests and client pages for the features you need, split things into separate components when they need to be reused, search Google for a library when you suspect one already does what you need, and so on. Before you know it, you end up with this. The arrows overlap so much that it’s hard to follow any one of them, so I’d suggest just looking at what components there are and which external libraries I used (the red boxes). overall server details client details
3y ago · #CS #창업 #BuyBus
Lately, I’ve been working on a side project alongside my startup team’s work. The frontend and backend have each come far enough that it’s time to connect them (I’ll probably write about what the project is when I release its MVP). I didn’t want to pay for EC2, and sharing the Raspberry Pi that runs gunh.ee seemed complicated, so I reinitialized and booted up the other Raspberry Pi I’d set aside because of an Ethernet cable issue in my previous post . The Ethernet interface still isn’t showing up, but speed isn’t an immediate concern, so I’ll deal with that later. Raspberry party To distinguish inbound traffic directed at our home’s single public IP address, the two servers need to use different external ports. Port numbers have conventional uses: 22 for SSH, 80 for HTTP, and 443 for HTTPS, for example. So I left those external port numbers as they are for the gunh.ee server, added 10000 to each for the side project, and configured the router to translate traffic headed for the side project to the corresponding conventional internal port numbers by subtracting 10000. The top three entries are for gunh.ee; the rest are for the side project. Every time I do something like this, I’m reminded how much taking Intro to Computer Networks has helped. Thank you, Professor Moon. ︙ I already went through the Ubuntu setup process when setting up gunh.ee, but there are still a few points that trip me up sometimes, so I’ll jot them down here. (On a Mac) The entire process of downloading an Ubuntu image, writing it to an SD card, and booting from it is described in detail here . To format the SD card, select it in Disk Utility, click ‘Erase,’ and choose ‘MS-DOS (FAT32)’. To write the downloaded image file to the SD card, use the following command. Leave the image file compressed. sudo sh -c 'gunzip -c ~/Downloads/ | sudo dd of= bs=32m' Once it has booted, enter your Wi-Fi details in /etc/netplan/50-cloud-init.yaml as described here , save the file, and reboot. /etc/network/interfaces is a file used by ifconfig , but ifconfig isn’t installed in the initial Ubuntu setup, so entering the information there won’t help.
3y ago · #CS #웹개발

I’m writing this to celebrate successfully connecting the gunh.ee server to Ethernet today. Here’s a shocking fact about gunh.ee: the server hosting it is a Raspberry Pi behind the TV in my living room. A photo I took when I first plugged it in on December 13, 2021 With so many hosting services available, why did I take the hard route and set up a server computer myself? Well... Hosting services fall into two broad categories: shared hosting and VPS hosting. The former is the cheapest way to launch a website, and it’s what I used for my first site, which I launched in the fall of my freshman year of college. The trouble is that the low price comes with limited flexibility. It supported everything needed to run a basic website, but I couldn’t run anything else. Of course, I didn’t know much back then, so it was plenty useful to me. I had a great time experimenting with and learning from the tools it provided. By the end of my senior year, I wanted to do much more with my new server. I wanted to write and run my own web server in node.js, create APIs, and use it for things beyond the web. For that, I needed VPS hosting. With a VPS, I wouldn’t have the physical machine, but I could install and use whatever software I wanted within the space allocated to me. The company I’d used as a freshman offered VPS hosting too, but this time I decided to try AWS EC2 for its flexible resource allocation and reputation, among other things (though EC2 differs somewhat from a VPS in how it handles virtualization , they’re similar enough here). The temporary landing page I put a fair bit of work into I created an EC2 instance, connected my domain, and put up a temporary landing page. A month or two later, the instance fee came out of my bank account. I don’t remember exactly how much it was, but it wasn’t unaffordable. Still, the thought of another monthly expense bothered me, and I wanted to avoid it if I could. That’s when I remembered the Raspberry Pis lying around my house. It’s harder to bring myself to pay for something intangible They were two Raspberry Pi 3 Model B+ boards I’d picked up in my department’s student room about a year earlier. The boards were in a box with some sensors and wires, and the lid said anyone who needed them could take them. They must have been left over from a major course or side project. I hadn’t brought them home with this in mind, but they seemed perfectly suitable as servers. Their performance was bound to be lousy, but each was a complete computer. And since they weren’t particularly powerful, it would be a shame to leave them sitting unused. As soon as the semester ended, I got to work setting up the server. There was far more to do than with EC2. With EC2, I could choose an operating system, set a few port rules, and connect remotely over SSH right away. With the Raspberry Pi, I had to do everything myself: format the SD card that would serve as its main storage, download an Ubuntu image and boot it, connect to the network, and set up port forwarding for SSH. The Raspberry Pi has no screen, and I didn’t have an external monitor, so I connected it to the living-room TV over HDMI and sat on the floor to work. It ended up behind the TV partly because the router was nearby and things there rarely got moved, but mostly because I had to do all the CLI work on the TV until I could connect over SSH. I spent three or four days doing almost nothing else. I obtained an SSL certificate, got HTTPS working, built the Vue.js project I’d been developing locally, and uploaded it to the server. I can’t tell you how happy I was when I finally confirmed that I could access the site on my iPhone. December 18, 2021 A screenshot I took then. The post page looks a little different now: there’s no longer a cover image or an emoji in the header. I wanted the site to feel modern but understated. When I started developing it, I thought Notion’s design was excellent, so I exported a Notion page as HTML and copied out its entire stylesheet. I made some changes where needed, but as I built the pages while largely keeping that style, I suddenly wondered: is this really understated? The emojis that often appear on Notion pages felt youthful and fresh, but they could also be distracting. On a site centered on writing, they would make the text feel less compact. So I kept refining the pages, using emojis and images only where necessary and minimizing the use of color to preserve that understated feel. While building the site, I also thought the design of the Chosun Ilbo website was good (regardless of politics). And when I visited New York late last year, I felt that the websites for MoMA and the Whitney Museum were aiming for something similar. Take a look at all three and you’ll probably get a sense of the look I’m after. Actually, the development story above was supposed to go in this site’s first and second posts . But I tried to fit everything I’d learned and felt at the time into a single post, ran out of steam halfway through, and abandoned it. Only now, after forgetting so much, can I sit down and sum up the whole process in one go. I might as well dump my notes on reference sources here, too ⋮ The point is that this site runs on a tiny Raspberry Pi behind my living-room TV. In other words, every time you visit gunh.ee, your request comes through my house before the response heads back to your device. ... Back to today. Since the server went live, I’ve used it for quite a few things besides publishing blog posts. Above all, it’s been incredibly convenient for testing web-service deployments. Deploying something under a new domain meant buying that domain, finding a hosting service, and waiting for DNS propagation—all of which took time and money. Creating a new subdomain on gunh.ee solved all of those problems. Today’s idea to connect the Raspberry Pi, which had been relying on WLAN, to Ethernet came to me while I was planning to test a new service on gunh.ee. Before testing a whole lot of request-response exchanges, I figured I should optimize the server’s connection. This wasn’t my first attempt to switch to Ethernet. I’d long felt that images in my blog posts loaded too slowly. At first I thought the Raspberry Pi’s processing speed was to blame, but the more I thought about it, the more likely it seemed that image sizes and connection speed were the problem. I was u
3y ago · #CS #웹개발
It's been ages since I last came to Anam 🍓🍓🍓 Aw, I'm honored 🍓🍓🍓 At Hongdoya, it's fried peppers and makgeolli Hahaha, it's still freaking hilarious even when I'm sober Collected 1 and 2 That 601 is the bus I need to transfer to Ran like crazy and made it on board
4y ago · #CS #웹개발 #해커톤
Hello! We're Team Bokumjari Strawberry Jam. ... We logged back in on another device, so our team name became Apple Jam But they actually sell apple jam? Why is my hair such a mess? --> --> Timeline by Role Planning & design Backend Frontend Planning Design Frontend/backend (me) Frontend/backend Frontend 19th 16:00 Check in, travel (Toyoko Inn → Times Square) 16:30 17:00 Dinner (Ongijeong, Times Square branch) 17:30 18:00 Travel (Times Square → All That Mind) 18:30 19:00 Theme announcement, brainstorming, sharing ideas 19:30 20:00 20:30 Settle on the idea <Service for Sharing Upcoming Vacant Subway Seats>, detailed planning 21:00 21:30 22:00 Detailed planning and design, writing user stories and preparing the idea presentation Set up AWS RDS Set up AWS RDS Initial React project setup 22:30 Prepare presentation 23:00 Team idea presentations 23:30 20th 0:00 Midnight event <Bingo> 0:30 1:00 Create wireframes (colors, fonts, page views) Plan MySQL table schema Plan routes 1:30 2:00 Travel (All That Mind → Toyoko Inn) ? 2:30 Get ready ? 3:00 Sleep 3:30 4:00 4:30
4y ago · #CS #웹개발 #해커톤

Work in progress. From the 19th to the 21st, I participated in <Korea University Summer Hackathon: A Voyage Together>, hosted by Korea University’s [ software development and research society DevKor · Design and Formative Arts Emergency Committee · Business School Student Council ]. I learned about it from a promotional post in the KAIST School of Computing class of 2018 group chat. I’d wanted to try a hackathon at least once, and the dates didn’t conflict with my lab internship, so it was a great opportunity. The application asked for some basic personal information and a portfolio in any format. I hadn’t written a CV or portfolio recently, so I took the opportunity to make a new page on my website. My education and work experience had been sitting, not quite organized, near the bottom of the homepage; moving them to a separate page made everything look much cleaner. If you’re interested, take a look ~ . I remember struggling to find anything substantial to put in personal statements in my first and second years of college, so it feels good to have something to write about now. Each team had five members—one planner, one designer, and three developers—and with twenty teams, the hackathon had around 100 participants in total. I considered gathering a few friends interested in development and forming a team together, but that didn’t fit the spirit of the event. I also thought working with entirely new people would be worthwhile, so I applied on my own. Each team had one leader, regardless of their role, and the application asked in advance whether you wanted to lead. I didn’t have a strong preference either way, so I selected “Not sure.” After my participation was confirmed, though, the organizers contacted me personally to ask if I could be a leader. I guess fewer than twenty people had volunteered. Since they asked, I couldn’t bring myself to say no, so I agreed. On the evening of the 13th, a week before the event, there was an online pre-event to form teams that would plan and develop services together at the main event. Team leaders gave idea pitches introducing themselves and the kinds of services they wanted to make, and the other participants listened and applied to join a leader’s team. Idea pitches. Pitching an idea without knowing the theme was a bit funny, but it was unavoidable for a hackathon where advance work wasn’t allowed and the theme would be revealed on the day. So instead of proposing a specific idea, I introduced things I’d developed and described the motivation they shared: an eye for problems across different fields and the drive to act on them. To be honest, I didn’t prepare very hard for my pitch. The allotted time was quite short—two minutes and thirty seconds—and I’d only agreed to be a leader the day before the pre-event, so there wasn’t much time to prepare. Above all, as a fifth-year undergraduate who’d been around the block, I can’t deny that I rather arrogantly assumed my fellow undergraduates couldn’t have done all that much (the event was open only to undergraduates). But wow, the moment I heard the first leader’s presentation, alarm bells went off. They were far better prepared than I’d expected! And it wasn’t just the first person. The second did well, and so did the next. Some had remarkable accomplishments; others, even without those, had a clear philosophy and conveyed it remarkably well. As I listened, I was suddenly afraid that, far from having the upper hand as a leader in this team-building process, I might be the one desperately hoping to be picked. My turn was fourth or fifth from last, and while I waited, I hastily worked a philosophy of my own into my pitch. I finished with a presentation I wasn’t ashamed of, though I wasn’t entirely satisfied with it either. A reminder not to let my guard down or get conceited: I need to step out into the world now and then and remember how small I am.
4y ago · #CS #웹개발 #해커톤

Originally posted on Instagram on July 27, 2019
7y ago · #인스타그램 #CS #웹개발

Around the start of the fall semester, I suddenly became interested in computer graphics. I had a vague idea that objects were represented as triangular surfaces and that each triangle was projected onto a plane to determine which pixels to display. But I knew nothing about the geometry required for projection, or about textures and lighting. While looking for a resource that would help me learn these things as I built a graphics engine myself, I came across a YouTube tutorial that seemed perfect. It used no graphics libraries such as OpenGL; its only interface to the computer screen was a function that printed a character corresponding to an individual pixel at a specified position. The tutorial had four parts, covering everything from basic projective geometry to textures. It was exactly the guide I wanted, with one problem: the pixel-printing function belonged to the Windows console API and worked only on Windows. Since I use a MacBook, I needed to find a replacement. Xcode might have let me develop a console application with similar functionality, but with the semester about to begin, I wasn't up for digging into a new development tool. So I put the project on hold. This week, after the semester ended, I returned to the project. Sitting down to work on it again gave me a new goal: this time, I would build a graphics engine using only what I already knew, without consulting any outside resources. Understanding the principles mattered more to me than optimizing performance, so I chose Python, which would let me turn ideas into code quickly. To draw pixels, I could simply create and manipulate a two-dimensional array of characters large enough to fill the console, then print it. I got straight to coding. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from time import sleep, time class XY: def __init__( self , x, y): self .x = x self .y = y WIDTH, HEIGHT = 100 , 30 SCREEN_BASE = [[ ' ' for _ in range (WIDTH)] for _ in range (HEIGHT)] SCREEN = SCREEN_BASE.copy() def clear(): SCREEN = SCREEN_BASE.copy() def fill(xy): SCREEN[HEIGHT - 1 - xy.y][xy.x] = '▇' def render(pixels): clear() for pixel in pixels: fill(pixel) output = ' ' .join( '' .join(col for col in row) for row in SCREEN) print (output) <div sty
4y ago · #CS #CG

© 2026 Gunhee Yi