Alibaba · model family

Strip Watermarks from Qwen Output

Qwen is one of the most widely downloaded open-weight families, which means a Qwen page cannot assume a single product. The same weights are reached through Qwen Chat in a browser, through Alibaba Cloud Model Studio and its OpenAI-compatible endpoint, through Together, Fireworks or OpenRouter, and through Ollama, LM Studio and llama.cpp on a local machine. It is also used heavily for non-English work, which makes one part of this scan a judgement call rather than a fix, and that part is explained below.

Scan your Qwen code now

Free, and it reports every removal by codepoint and line.

Open the scanner

What we measured

68

code-generation calls

17

provider and model targets

59,486

characters generated

0

contained a hidden character

On 2026-08-12 we sent identical code-writing prompts to every model our own gateway can reach and scanned each raw API response. Not one of them contained a zero-width character, a bidirectional control, or a tag character.

3 of the 68 answers contained typographic punctuation, and only in the prose-heavy prompts rather than in the plain code one. The most common was the non-breaking hyphen, which is visible but still breaks a copied command. 2 left trailing whitespace.

The useful conclusion is the boring one: raw model output is essentially clean, so when you do find hidden characters in your file, they almost certainly came from the path the text travelled rather than from the model. That is what the section below is about.

Scope: this measured API output from models we can reach directly. It did not measure the Qwen web app, which is the point being made, since the browser is where the characters get added.

How code gets out of Qwen, and what each path adds

A local build through Ollama, LM Studio or llama.cpp low risk

This is the most common way Qwen actually reaches a file, and it is the shortest path there is: tokens decode to UTF-8 and a script writes them out. No HTML exists anywhere in the chain, so none of the browser-typography substitutions can occur. The trade is that nothing filters or displays the string before it is saved, so a bidi control or a Unicode tag payload that arrived through your prompt, a retrieved document or a pasted log is written to disk unaltered.

Copying from the Qwen Chat web app medium risk

Rendered chat output is HTML, and HTML carries no-break spaces, curly quotes, dashes and soft hyphens as ordinary content. Copy a code block and you usually get the raw text; copy across the boundary into surrounding prose and you get the rendered version of that prose too. In text that mixes Chinese and code this is compounded by the ideographic space U+3000, which is a legitimate character in Chinese typography and a syntax error in most programming languages.

The Model Studio or DashScope API low risk

The response is a raw JSON string, so the transport adds nothing and the only characters present are ones the model produced or your context supplied. This is the right path to prefer whenever you have a choice, because it removes the rendering layer entirely. It does not remove the need to scan, since prompt-carried characters pass straight through it.

Qwen behind a coding agent or IDE extension medium risk

Qwen3-Coder and the Qwen Code CLI are often wired into editors or agents that write files without showing you a diff first. Context for those requests is assembled from your repository, fetched pages and issue text, so anything invisible already in the repository can be reproduced into new files. Scan the file after the write, not the model response in isolation.

The look-alike letter check is the part of this tool that a Qwen user needs to understand properly, because Qwen is routinely used for Russian, Ukrainian, Greek and Chinese work. A Cyrillic small a inside an ASCII identifier, a package name or a URL is a supply-chain trick: it compiles, it reads as Latin, and it points somewhere else. The identical character inside a Russian comment or string is simply Russian, and nothing is wrong with it. The tool cannot tell those apart without understanding the language, so it never rewrites them by default: it reports each one with its codepoint and line number and leaves the decision to you, and the replace option exists only for people who know their file should be pure ASCII.

What this does not do

It does not remove statistical watermarking. Schemes of the SynthID family add no characters at all: they bias which token the model samples, so the signal lives in word choice across the whole output and nothing you can delete carries it. Attacking that means rewriting the text, which for source code risks changing what it does.

This is a hygiene and security tool, not an attribution bypass. Formatters already normalise surface signals, and what identifies generated code is structure and style rather than hidden bytes. Disclose AI assistance wherever you are asked to.

Qwen questions

My comments are in Russian and the scan flagged dozens of look-alike letters. Will it wreck them? +

Not unless you ask it to. Look-alike replacement is off by default precisely because a Cyrillic letter in Cyrillic prose is correct text, and rewriting it would corrupt your file. The report still lists every one by line so you can look at them, which is the point: you are checking whether any of them sit inside an identifier, an import path or a URL rather than inside a sentence. Leave the replace option off for multilingual work.

Why report look-alikes at all if you are not going to fix them? +

Because the dangerous case and the innocent case are the same codepoint. A tool that replaced them silently would break every Russian comment in the codebase to catch one poisoned identifier, and a tool that ignored them would miss the identifier entirely. Reporting with a line number is the only honest option: it costs you a glance and it puts a human on the one decision a program cannot make.

The scan changed U+3000 in my Chinese text. Was that right? +

For code, yes: the ideographic space is folded to an ordinary space because it is whitespace that is not U+0020, and inside indentation or an identifier it breaks things while looking correct. For Chinese prose the fold is visible, since two ideographic spaces are how a paragraph is indented. If your input is documentation rather than source, check that substitution before you accept the output.

Does it matter which provider I got the weights from? +

For characters, only through the chat template and the surrounding product. The weights are the weights, but a hosted endpoint, a local GGUF build and the vendor chat app each wrap them differently and each hand the result to a different consumer, and it is that last step that decides whether HTML gets involved. Scan at the point the text becomes a file and the provider question stops mattering.

Other tools